14f44304bSSimon Glass# 24f44304bSSimon Glass# Copyright (c) 2016 Google, Inc 34f44304bSSimon Glass# Written by Simon Glass <sjg@chromium.org> 44f44304bSSimon Glass# 54f44304bSSimon Glass# SPDX-License-Identifier: GPL-2.0+ 64f44304bSSimon Glass# 74f44304bSSimon Glass# To run a single test, change to this directory, and: 84f44304bSSimon Glass# 94f44304bSSimon Glass# python -m unittest func_test.TestFunctional.testHelp 104f44304bSSimon Glass 114f44304bSSimon Glassfrom optparse import OptionParser 124f44304bSSimon Glassimport os 134f44304bSSimon Glassimport shutil 144f44304bSSimon Glassimport struct 154f44304bSSimon Glassimport sys 164f44304bSSimon Glassimport tempfile 174f44304bSSimon Glassimport unittest 184f44304bSSimon Glass 194f44304bSSimon Glassimport binman 204f44304bSSimon Glassimport cmdline 214f44304bSSimon Glassimport command 224f44304bSSimon Glassimport control 234f44304bSSimon Glassimport entry 24*99ed4a2eSSimon Glassimport fdt 254f44304bSSimon Glassimport fdt_util 264f44304bSSimon Glassimport tools 274f44304bSSimon Glassimport tout 284f44304bSSimon Glass 294f44304bSSimon Glass# Contents of test files, corresponding to different entry types 304f44304bSSimon GlassU_BOOT_DATA = '1234' 314f44304bSSimon GlassU_BOOT_IMG_DATA = 'img' 324f44304bSSimon GlassU_BOOT_SPL_DATA = '567' 334f44304bSSimon GlassBLOB_DATA = '89' 344f44304bSSimon GlassME_DATA = '0abcd' 354f44304bSSimon GlassVGA_DATA = 'vga' 364f44304bSSimon GlassU_BOOT_DTB_DATA = 'udtb' 374f44304bSSimon GlassX86_START16_DATA = 'start16' 384f44304bSSimon GlassU_BOOT_NODTB_DATA = 'nodtb with microcode pointer somewhere in here' 39da229090SSimon GlassFSP_DATA = 'fsp' 40da229090SSimon GlassCMC_DATA = 'cmc' 414f44304bSSimon Glass 424f44304bSSimon Glassclass TestFunctional(unittest.TestCase): 434f44304bSSimon Glass """Functional tests for binman 444f44304bSSimon Glass 454f44304bSSimon Glass Most of these use a sample .dts file to build an image and then check 464f44304bSSimon Glass that it looks correct. The sample files are in the test/ subdirectory 474f44304bSSimon Glass and are numbered. 484f44304bSSimon Glass 494f44304bSSimon Glass For each entry type a very small test file is created using fixed 504f44304bSSimon Glass string contents. This makes it easy to test that things look right, and 514f44304bSSimon Glass debug problems. 524f44304bSSimon Glass 534f44304bSSimon Glass In some cases a 'real' file must be used - these are also supplied in 544f44304bSSimon Glass the test/ diurectory. 554f44304bSSimon Glass """ 564f44304bSSimon Glass @classmethod 574f44304bSSimon Glass def setUpClass(self): 584f44304bSSimon Glass # Handle the case where argv[0] is 'python' 594f44304bSSimon Glass self._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) 604f44304bSSimon Glass self._binman_pathname = os.path.join(self._binman_dir, 'binman') 614f44304bSSimon Glass 624f44304bSSimon Glass # Create a temporary directory for input files 634f44304bSSimon Glass self._indir = tempfile.mkdtemp(prefix='binmant.') 644f44304bSSimon Glass 654f44304bSSimon Glass # Create some test files 664f44304bSSimon Glass TestFunctional._MakeInputFile('u-boot.bin', U_BOOT_DATA) 674f44304bSSimon Glass TestFunctional._MakeInputFile('u-boot.img', U_BOOT_IMG_DATA) 684f44304bSSimon Glass TestFunctional._MakeInputFile('spl/u-boot-spl.bin', U_BOOT_SPL_DATA) 694f44304bSSimon Glass TestFunctional._MakeInputFile('blobfile', BLOB_DATA) 70e0ff8551SSimon Glass TestFunctional._MakeInputFile('me.bin', ME_DATA) 71e0ff8551SSimon Glass TestFunctional._MakeInputFile('vga.bin', VGA_DATA) 724f44304bSSimon Glass TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA) 73e0ff8551SSimon Glass TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA) 744f44304bSSimon Glass TestFunctional._MakeInputFile('u-boot-nodtb.bin', U_BOOT_NODTB_DATA) 75da229090SSimon Glass TestFunctional._MakeInputFile('fsp.bin', FSP_DATA) 76da229090SSimon Glass TestFunctional._MakeInputFile('cmc.bin', CMC_DATA) 774f44304bSSimon Glass self._output_setup = False 784f44304bSSimon Glass 79e0ff8551SSimon Glass # ELF file with a '_dt_ucode_base_size' symbol 80e0ff8551SSimon Glass with open(self.TestFile('u_boot_ucode_ptr')) as fd: 81e0ff8551SSimon Glass TestFunctional._MakeInputFile('u-boot', fd.read()) 82e0ff8551SSimon Glass 83e0ff8551SSimon Glass # Intel flash descriptor file 84e0ff8551SSimon Glass with open(self.TestFile('descriptor.bin')) as fd: 85e0ff8551SSimon Glass TestFunctional._MakeInputFile('descriptor.bin', fd.read()) 86e0ff8551SSimon Glass 874f44304bSSimon Glass @classmethod 884f44304bSSimon Glass def tearDownClass(self): 894f44304bSSimon Glass """Remove the temporary input directory and its contents""" 904f44304bSSimon Glass if self._indir: 914f44304bSSimon Glass shutil.rmtree(self._indir) 924f44304bSSimon Glass self._indir = None 934f44304bSSimon Glass 944f44304bSSimon Glass def setUp(self): 954f44304bSSimon Glass # Enable this to turn on debugging output 964f44304bSSimon Glass # tout.Init(tout.DEBUG) 974f44304bSSimon Glass command.test_result = None 984f44304bSSimon Glass 994f44304bSSimon Glass def tearDown(self): 1004f44304bSSimon Glass """Remove the temporary output directory""" 1014f44304bSSimon Glass tools._FinaliseForTest() 1024f44304bSSimon Glass 1034f44304bSSimon Glass def _RunBinman(self, *args, **kwargs): 1044f44304bSSimon Glass """Run binman using the command line 1054f44304bSSimon Glass 1064f44304bSSimon Glass Args: 1074f44304bSSimon Glass Arguments to pass, as a list of strings 1084f44304bSSimon Glass kwargs: Arguments to pass to Command.RunPipe() 1094f44304bSSimon Glass """ 1104f44304bSSimon Glass result = command.RunPipe([[self._binman_pathname] + list(args)], 1114f44304bSSimon Glass capture=True, capture_stderr=True, raise_on_error=False) 1124f44304bSSimon Glass if result.return_code and kwargs.get('raise_on_error', True): 1134f44304bSSimon Glass raise Exception("Error running '%s': %s" % (' '.join(args), 1144f44304bSSimon Glass result.stdout + result.stderr)) 1154f44304bSSimon Glass return result 1164f44304bSSimon Glass 1174f44304bSSimon Glass def _DoBinman(self, *args): 1184f44304bSSimon Glass """Run binman using directly (in the same process) 1194f44304bSSimon Glass 1204f44304bSSimon Glass Args: 1214f44304bSSimon Glass Arguments to pass, as a list of strings 1224f44304bSSimon Glass Returns: 1234f44304bSSimon Glass Return value (0 for success) 1244f44304bSSimon Glass """ 1254f44304bSSimon Glass (options, args) = cmdline.ParseArgs(list(args)) 1264f44304bSSimon Glass options.pager = 'binman-invalid-pager' 1274f44304bSSimon Glass options.build_dir = self._indir 1284f44304bSSimon Glass 1294f44304bSSimon Glass # For testing, you can force an increase in verbosity here 1304f44304bSSimon Glass # options.verbosity = tout.DEBUG 1314f44304bSSimon Glass return control.Binman(options, args) 1324f44304bSSimon Glass 1334f44304bSSimon Glass def _DoTestFile(self, fname): 1344f44304bSSimon Glass """Run binman with a given test file 1354f44304bSSimon Glass 1364f44304bSSimon Glass Args: 1374f44304bSSimon Glass fname: Device tree source filename to use (e.g. 05_simple.dts) 1384f44304bSSimon Glass """ 1394f44304bSSimon Glass return self._DoBinman('-p', '-I', self._indir, 1404f44304bSSimon Glass '-d', self.TestFile(fname)) 1414f44304bSSimon Glass 1424f44304bSSimon Glass def _SetupDtb(self, fname, outfile='u-boot.dtb'): 143e0ff8551SSimon Glass """Set up a new test device-tree file 144e0ff8551SSimon Glass 145e0ff8551SSimon Glass The given file is compiled and set up as the device tree to be used 146e0ff8551SSimon Glass for ths test. 147e0ff8551SSimon Glass 148e0ff8551SSimon Glass Args: 149e0ff8551SSimon Glass fname: Filename of .dts file to read 150e0ff8551SSimon Glass outfile: Output filename for compiled device tree binary 151e0ff8551SSimon Glass 152e0ff8551SSimon Glass Returns: 153e0ff8551SSimon Glass Contents of device tree binary 154e0ff8551SSimon Glass """ 1554f44304bSSimon Glass if not self._output_setup: 1564f44304bSSimon Glass tools.PrepareOutputDir(self._indir, True) 1574f44304bSSimon Glass self._output_setup = True 1584f44304bSSimon Glass dtb = fdt_util.EnsureCompiled(self.TestFile(fname)) 1594f44304bSSimon Glass with open(dtb) as fd: 1604f44304bSSimon Glass data = fd.read() 1614f44304bSSimon Glass TestFunctional._MakeInputFile(outfile, data) 162e0ff8551SSimon Glass return data 1634f44304bSSimon Glass 164e0ff8551SSimon Glass def _DoReadFileDtb(self, fname, use_real_dtb=False): 1654f44304bSSimon Glass """Run binman and return the resulting image 1664f44304bSSimon Glass 1674f44304bSSimon Glass This runs binman with a given test file and then reads the resulting 1684f44304bSSimon Glass output file. It is a shortcut function since most tests need to do 1694f44304bSSimon Glass these steps. 1704f44304bSSimon Glass 1714f44304bSSimon Glass Raises an assertion failure if binman returns a non-zero exit code. 1724f44304bSSimon Glass 1734f44304bSSimon Glass Args: 1744f44304bSSimon Glass fname: Device tree source filename to use (e.g. 05_simple.dts) 1754f44304bSSimon Glass use_real_dtb: True to use the test file as the contents of 1764f44304bSSimon Glass the u-boot-dtb entry. Normally this is not needed and the 1774f44304bSSimon Glass test contents (the U_BOOT_DTB_DATA string) can be used. 1784f44304bSSimon Glass But in some test we need the real contents. 179e0ff8551SSimon Glass 180e0ff8551SSimon Glass Returns: 181e0ff8551SSimon Glass Tuple: 182e0ff8551SSimon Glass Resulting image contents 183e0ff8551SSimon Glass Device tree contents 1844f44304bSSimon Glass """ 185e0ff8551SSimon Glass dtb_data = None 1864f44304bSSimon Glass # Use the compiled test file as the u-boot-dtb input 1874f44304bSSimon Glass if use_real_dtb: 188e0ff8551SSimon Glass dtb_data = self._SetupDtb(fname) 1894f44304bSSimon Glass 1904f44304bSSimon Glass try: 1914f44304bSSimon Glass retcode = self._DoTestFile(fname) 1924f44304bSSimon Glass self.assertEqual(0, retcode) 1934f44304bSSimon Glass 1944f44304bSSimon Glass # Find the (only) image, read it and return its contents 1954f44304bSSimon Glass image = control.images['image'] 1964f44304bSSimon Glass fname = tools.GetOutputFilename('image.bin') 1974f44304bSSimon Glass self.assertTrue(os.path.exists(fname)) 1984f44304bSSimon Glass with open(fname) as fd: 199e0ff8551SSimon Glass return fd.read(), dtb_data 2004f44304bSSimon Glass finally: 2014f44304bSSimon Glass # Put the test file back 2024f44304bSSimon Glass if use_real_dtb: 2034f44304bSSimon Glass TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA) 2044f44304bSSimon Glass 205e0ff8551SSimon Glass def _DoReadFile(self, fname, use_real_dtb=False): 206e0ff8551SSimon Glass """Helper function which discards the device-tree binary""" 207e0ff8551SSimon Glass return self._DoReadFileDtb(fname, use_real_dtb)[0] 208e0ff8551SSimon Glass 2094f44304bSSimon Glass @classmethod 2104f44304bSSimon Glass def _MakeInputFile(self, fname, contents): 2114f44304bSSimon Glass """Create a new test input file, creating directories as needed 2124f44304bSSimon Glass 2134f44304bSSimon Glass Args: 2144f44304bSSimon Glass fname: Filenaem to create 2154f44304bSSimon Glass contents: File contents to write in to the file 2164f44304bSSimon Glass Returns: 2174f44304bSSimon Glass Full pathname of file created 2184f44304bSSimon Glass """ 2194f44304bSSimon Glass pathname = os.path.join(self._indir, fname) 2204f44304bSSimon Glass dirname = os.path.dirname(pathname) 2214f44304bSSimon Glass if dirname and not os.path.exists(dirname): 2224f44304bSSimon Glass os.makedirs(dirname) 2234f44304bSSimon Glass with open(pathname, 'wb') as fd: 2244f44304bSSimon Glass fd.write(contents) 2254f44304bSSimon Glass return pathname 2264f44304bSSimon Glass 2274f44304bSSimon Glass @classmethod 2284f44304bSSimon Glass def TestFile(self, fname): 2294f44304bSSimon Glass return os.path.join(self._binman_dir, 'test', fname) 2304f44304bSSimon Glass 2314f44304bSSimon Glass def AssertInList(self, grep_list, target): 2324f44304bSSimon Glass """Assert that at least one of a list of things is in a target 2334f44304bSSimon Glass 2344f44304bSSimon Glass Args: 2354f44304bSSimon Glass grep_list: List of strings to check 2364f44304bSSimon Glass target: Target string 2374f44304bSSimon Glass """ 2384f44304bSSimon Glass for grep in grep_list: 2394f44304bSSimon Glass if grep in target: 2404f44304bSSimon Glass return 2414f44304bSSimon Glass self.fail("Error: '%' not found in '%s'" % (grep_list, target)) 2424f44304bSSimon Glass 2434f44304bSSimon Glass def CheckNoGaps(self, entries): 2444f44304bSSimon Glass """Check that all entries fit together without gaps 2454f44304bSSimon Glass 2464f44304bSSimon Glass Args: 2474f44304bSSimon Glass entries: List of entries to check 2484f44304bSSimon Glass """ 2494f44304bSSimon Glass pos = 0 2504f44304bSSimon Glass for entry in entries.values(): 2514f44304bSSimon Glass self.assertEqual(pos, entry.pos) 2524f44304bSSimon Glass pos += entry.size 2534f44304bSSimon Glass 254e0ff8551SSimon Glass def GetFdtLen(self, dtb): 255e0ff8551SSimon Glass """Get the totalsize field from a device tree binary 256e0ff8551SSimon Glass 257e0ff8551SSimon Glass Args: 258e0ff8551SSimon Glass dtb: Device tree binary contents 259e0ff8551SSimon Glass 260e0ff8551SSimon Glass Returns: 261e0ff8551SSimon Glass Total size of device tree binary, from the header 262e0ff8551SSimon Glass """ 263e0ff8551SSimon Glass return struct.unpack('>L', dtb[4:8])[0] 264e0ff8551SSimon Glass 2654f44304bSSimon Glass def testRun(self): 2664f44304bSSimon Glass """Test a basic run with valid args""" 2674f44304bSSimon Glass result = self._RunBinman('-h') 2684f44304bSSimon Glass 2694f44304bSSimon Glass def testFullHelp(self): 2704f44304bSSimon Glass """Test that the full help is displayed with -H""" 2714f44304bSSimon Glass result = self._RunBinman('-H') 2724f44304bSSimon Glass help_file = os.path.join(self._binman_dir, 'README') 2734f44304bSSimon Glass self.assertEqual(len(result.stdout), os.path.getsize(help_file)) 2744f44304bSSimon Glass self.assertEqual(0, len(result.stderr)) 2754f44304bSSimon Glass self.assertEqual(0, result.return_code) 2764f44304bSSimon Glass 2774f44304bSSimon Glass def testFullHelpInternal(self): 2784f44304bSSimon Glass """Test that the full help is displayed with -H""" 2794f44304bSSimon Glass try: 2804f44304bSSimon Glass command.test_result = command.CommandResult() 2814f44304bSSimon Glass result = self._DoBinman('-H') 2824f44304bSSimon Glass help_file = os.path.join(self._binman_dir, 'README') 2834f44304bSSimon Glass finally: 2844f44304bSSimon Glass command.test_result = None 2854f44304bSSimon Glass 2864f44304bSSimon Glass def testHelp(self): 2874f44304bSSimon Glass """Test that the basic help is displayed with -h""" 2884f44304bSSimon Glass result = self._RunBinman('-h') 2894f44304bSSimon Glass self.assertTrue(len(result.stdout) > 200) 2904f44304bSSimon Glass self.assertEqual(0, len(result.stderr)) 2914f44304bSSimon Glass self.assertEqual(0, result.return_code) 2924f44304bSSimon Glass 2934f44304bSSimon Glass # Not yet available. 2944f44304bSSimon Glass def testBoard(self): 2954f44304bSSimon Glass """Test that we can run it with a specific board""" 2964f44304bSSimon Glass self._SetupDtb('05_simple.dts', 'sandbox/u-boot.dtb') 2974f44304bSSimon Glass TestFunctional._MakeInputFile('sandbox/u-boot.bin', U_BOOT_DATA) 2984f44304bSSimon Glass result = self._DoBinman('-b', 'sandbox') 2994f44304bSSimon Glass self.assertEqual(0, result) 3004f44304bSSimon Glass 3014f44304bSSimon Glass def testNeedBoard(self): 3024f44304bSSimon Glass """Test that we get an error when no board ius supplied""" 3034f44304bSSimon Glass with self.assertRaises(ValueError) as e: 3044f44304bSSimon Glass result = self._DoBinman() 3054f44304bSSimon Glass self.assertIn("Must provide a board to process (use -b <board>)", 3064f44304bSSimon Glass str(e.exception)) 3074f44304bSSimon Glass 3084f44304bSSimon Glass def testMissingDt(self): 3094f44304bSSimon Glass """Test that an invalid device tree file generates an error""" 3104f44304bSSimon Glass with self.assertRaises(Exception) as e: 3114f44304bSSimon Glass self._RunBinman('-d', 'missing_file') 3124f44304bSSimon Glass # We get one error from libfdt, and a different one from fdtget. 3134f44304bSSimon Glass self.AssertInList(["Couldn't open blob from 'missing_file'", 3144f44304bSSimon Glass 'No such file or directory'], str(e.exception)) 3154f44304bSSimon Glass 3164f44304bSSimon Glass def testBrokenDt(self): 3174f44304bSSimon Glass """Test that an invalid device tree source file generates an error 3184f44304bSSimon Glass 3194f44304bSSimon Glass Since this is a source file it should be compiled and the error 3204f44304bSSimon Glass will come from the device-tree compiler (dtc). 3214f44304bSSimon Glass """ 3224f44304bSSimon Glass with self.assertRaises(Exception) as e: 3234f44304bSSimon Glass self._RunBinman('-d', self.TestFile('01_invalid.dts')) 3244f44304bSSimon Glass self.assertIn("FATAL ERROR: Unable to parse input tree", 3254f44304bSSimon Glass str(e.exception)) 3264f44304bSSimon Glass 3274f44304bSSimon Glass def testMissingNode(self): 3284f44304bSSimon Glass """Test that a device tree without a 'binman' node generates an error""" 3294f44304bSSimon Glass with self.assertRaises(Exception) as e: 3304f44304bSSimon Glass self._DoBinman('-d', self.TestFile('02_missing_node.dts')) 3314f44304bSSimon Glass self.assertIn("does not have a 'binman' node", str(e.exception)) 3324f44304bSSimon Glass 3334f44304bSSimon Glass def testEmpty(self): 3344f44304bSSimon Glass """Test that an empty binman node works OK (i.e. does nothing)""" 3354f44304bSSimon Glass result = self._RunBinman('-d', self.TestFile('03_empty.dts')) 3364f44304bSSimon Glass self.assertEqual(0, len(result.stderr)) 3374f44304bSSimon Glass self.assertEqual(0, result.return_code) 3384f44304bSSimon Glass 3394f44304bSSimon Glass def testInvalidEntry(self): 3404f44304bSSimon Glass """Test that an invalid entry is flagged""" 3414f44304bSSimon Glass with self.assertRaises(Exception) as e: 3424f44304bSSimon Glass result = self._RunBinman('-d', 3434f44304bSSimon Glass self.TestFile('04_invalid_entry.dts')) 3444f44304bSSimon Glass #print e.exception 3454f44304bSSimon Glass self.assertIn("Unknown entry type 'not-a-valid-type' in node " 3464f44304bSSimon Glass "'/binman/not-a-valid-type'", str(e.exception)) 3474f44304bSSimon Glass 3484f44304bSSimon Glass def testSimple(self): 3494f44304bSSimon Glass """Test a simple binman with a single file""" 3504f44304bSSimon Glass data = self._DoReadFile('05_simple.dts') 3514f44304bSSimon Glass self.assertEqual(U_BOOT_DATA, data) 3524f44304bSSimon Glass 3534f44304bSSimon Glass def testDual(self): 3544f44304bSSimon Glass """Test that we can handle creating two images 3554f44304bSSimon Glass 3564f44304bSSimon Glass This also tests image padding. 3574f44304bSSimon Glass """ 3584f44304bSSimon Glass retcode = self._DoTestFile('06_dual_image.dts') 3594f44304bSSimon Glass self.assertEqual(0, retcode) 3604f44304bSSimon Glass 3614f44304bSSimon Glass image = control.images['image1'] 3624f44304bSSimon Glass self.assertEqual(len(U_BOOT_DATA), image._size) 3634f44304bSSimon Glass fname = tools.GetOutputFilename('image1.bin') 3644f44304bSSimon Glass self.assertTrue(os.path.exists(fname)) 3654f44304bSSimon Glass with open(fname) as fd: 3664f44304bSSimon Glass data = fd.read() 3674f44304bSSimon Glass self.assertEqual(U_BOOT_DATA, data) 3684f44304bSSimon Glass 3694f44304bSSimon Glass image = control.images['image2'] 3704f44304bSSimon Glass self.assertEqual(3 + len(U_BOOT_DATA) + 5, image._size) 3714f44304bSSimon Glass fname = tools.GetOutputFilename('image2.bin') 3724f44304bSSimon Glass self.assertTrue(os.path.exists(fname)) 3734f44304bSSimon Glass with open(fname) as fd: 3744f44304bSSimon Glass data = fd.read() 3754f44304bSSimon Glass self.assertEqual(U_BOOT_DATA, data[3:7]) 3764f44304bSSimon Glass self.assertEqual(chr(0) * 3, data[:3]) 3774f44304bSSimon Glass self.assertEqual(chr(0) * 5, data[7:]) 3784f44304bSSimon Glass 3794f44304bSSimon Glass def testBadAlign(self): 3804f44304bSSimon Glass """Test that an invalid alignment value is detected""" 3814f44304bSSimon Glass with self.assertRaises(ValueError) as e: 3824f44304bSSimon Glass self._DoTestFile('07_bad_align.dts') 3834f44304bSSimon Glass self.assertIn("Node '/binman/u-boot': Alignment 23 must be a power " 3844f44304bSSimon Glass "of two", str(e.exception)) 3854f44304bSSimon Glass 3864f44304bSSimon Glass def testPackSimple(self): 3874f44304bSSimon Glass """Test that packing works as expected""" 3884f44304bSSimon Glass retcode = self._DoTestFile('08_pack.dts') 3894f44304bSSimon Glass self.assertEqual(0, retcode) 3904f44304bSSimon Glass self.assertIn('image', control.images) 3914f44304bSSimon Glass image = control.images['image'] 3924f44304bSSimon Glass entries = image._entries 3934f44304bSSimon Glass self.assertEqual(5, len(entries)) 3944f44304bSSimon Glass 3954f44304bSSimon Glass # First u-boot 3964f44304bSSimon Glass self.assertIn('u-boot', entries) 3974f44304bSSimon Glass entry = entries['u-boot'] 3984f44304bSSimon Glass self.assertEqual(0, entry.pos) 3994f44304bSSimon Glass self.assertEqual(len(U_BOOT_DATA), entry.size) 4004f44304bSSimon Glass 4014f44304bSSimon Glass # Second u-boot, aligned to 16-byte boundary 4024f44304bSSimon Glass self.assertIn('u-boot-align', entries) 4034f44304bSSimon Glass entry = entries['u-boot-align'] 4044f44304bSSimon Glass self.assertEqual(16, entry.pos) 4054f44304bSSimon Glass self.assertEqual(len(U_BOOT_DATA), entry.size) 4064f44304bSSimon Glass 4074f44304bSSimon Glass # Third u-boot, size 23 bytes 4084f44304bSSimon Glass self.assertIn('u-boot-size', entries) 4094f44304bSSimon Glass entry = entries['u-boot-size'] 4104f44304bSSimon Glass self.assertEqual(20, entry.pos) 4114f44304bSSimon Glass self.assertEqual(len(U_BOOT_DATA), entry.contents_size) 4124f44304bSSimon Glass self.assertEqual(23, entry.size) 4134f44304bSSimon Glass 4144f44304bSSimon Glass # Fourth u-boot, placed immediate after the above 4154f44304bSSimon Glass self.assertIn('u-boot-next', entries) 4164f44304bSSimon Glass entry = entries['u-boot-next'] 4174f44304bSSimon Glass self.assertEqual(43, entry.pos) 4184f44304bSSimon Glass self.assertEqual(len(U_BOOT_DATA), entry.size) 4194f44304bSSimon Glass 4204f44304bSSimon Glass # Fifth u-boot, placed at a fixed position 4214f44304bSSimon Glass self.assertIn('u-boot-fixed', entries) 4224f44304bSSimon Glass entry = entries['u-boot-fixed'] 4234f44304bSSimon Glass self.assertEqual(61, entry.pos) 4244f44304bSSimon Glass self.assertEqual(len(U_BOOT_DATA), entry.size) 4254f44304bSSimon Glass 4264f44304bSSimon Glass self.assertEqual(65, image._size) 4274f44304bSSimon Glass 4284f44304bSSimon Glass def testPackExtra(self): 4294f44304bSSimon Glass """Test that extra packing feature works as expected""" 4304f44304bSSimon Glass retcode = self._DoTestFile('09_pack_extra.dts') 4314f44304bSSimon Glass 4324f44304bSSimon Glass self.assertEqual(0, retcode) 4334f44304bSSimon Glass self.assertIn('image', control.images) 4344f44304bSSimon Glass image = control.images['image'] 4354f44304bSSimon Glass entries = image._entries 4364f44304bSSimon Glass self.assertEqual(5, len(entries)) 4374f44304bSSimon Glass 4384f44304bSSimon Glass # First u-boot with padding before and after 4394f44304bSSimon Glass self.assertIn('u-boot', entries) 4404f44304bSSimon Glass entry = entries['u-boot'] 4414f44304bSSimon Glass self.assertEqual(0, entry.pos) 4424f44304bSSimon Glass self.assertEqual(3, entry.pad_before) 4434f44304bSSimon Glass self.assertEqual(3 + 5 + len(U_BOOT_DATA), entry.size) 4444f44304bSSimon Glass 4454f44304bSSimon Glass # Second u-boot has an aligned size, but it has no effect 4464f44304bSSimon Glass self.assertIn('u-boot-align-size-nop', entries) 4474f44304bSSimon Glass entry = entries['u-boot-align-size-nop'] 4484f44304bSSimon Glass self.assertEqual(12, entry.pos) 4494f44304bSSimon Glass self.assertEqual(4, entry.size) 4504f44304bSSimon Glass 4514f44304bSSimon Glass # Third u-boot has an aligned size too 4524f44304bSSimon Glass self.assertIn('u-boot-align-size', entries) 4534f44304bSSimon Glass entry = entries['u-boot-align-size'] 4544f44304bSSimon Glass self.assertEqual(16, entry.pos) 4554f44304bSSimon Glass self.assertEqual(32, entry.size) 4564f44304bSSimon Glass 4574f44304bSSimon Glass # Fourth u-boot has an aligned end 4584f44304bSSimon Glass self.assertIn('u-boot-align-end', entries) 4594f44304bSSimon Glass entry = entries['u-boot-align-end'] 4604f44304bSSimon Glass self.assertEqual(48, entry.pos) 4614f44304bSSimon Glass self.assertEqual(16, entry.size) 4624f44304bSSimon Glass 4634f44304bSSimon Glass # Fifth u-boot immediately afterwards 4644f44304bSSimon Glass self.assertIn('u-boot-align-both', entries) 4654f44304bSSimon Glass entry = entries['u-boot-align-both'] 4664f44304bSSimon Glass self.assertEqual(64, entry.pos) 4674f44304bSSimon Glass self.assertEqual(64, entry.size) 4684f44304bSSimon Glass 4694f44304bSSimon Glass self.CheckNoGaps(entries) 4704f44304bSSimon Glass self.assertEqual(128, image._size) 4714f44304bSSimon Glass 4724f44304bSSimon Glass def testPackAlignPowerOf2(self): 4734f44304bSSimon Glass """Test that invalid entry alignment is detected""" 4744f44304bSSimon Glass with self.assertRaises(ValueError) as e: 4754f44304bSSimon Glass self._DoTestFile('10_pack_align_power2.dts') 4764f44304bSSimon Glass self.assertIn("Node '/binman/u-boot': Alignment 5 must be a power " 4774f44304bSSimon Glass "of two", str(e.exception)) 4784f44304bSSimon Glass 4794f44304bSSimon Glass def testPackAlignSizePowerOf2(self): 4804f44304bSSimon Glass """Test that invalid entry size alignment is detected""" 4814f44304bSSimon Glass with self.assertRaises(ValueError) as e: 4824f44304bSSimon Glass self._DoTestFile('11_pack_align_size_power2.dts') 4834f44304bSSimon Glass self.assertIn("Node '/binman/u-boot': Alignment size 55 must be a " 4844f44304bSSimon Glass "power of two", str(e.exception)) 4854f44304bSSimon Glass 4864f44304bSSimon Glass def testPackInvalidAlign(self): 4874f44304bSSimon Glass """Test detection of an position that does not match its alignment""" 4884f44304bSSimon Glass with self.assertRaises(ValueError) as e: 4894f44304bSSimon Glass self._DoTestFile('12_pack_inv_align.dts') 4904f44304bSSimon Glass self.assertIn("Node '/binman/u-boot': Position 0x5 (5) does not match " 4914f44304bSSimon Glass "align 0x4 (4)", str(e.exception)) 4924f44304bSSimon Glass 4934f44304bSSimon Glass def testPackInvalidSizeAlign(self): 4944f44304bSSimon Glass """Test that invalid entry size alignment is detected""" 4954f44304bSSimon Glass with self.assertRaises(ValueError) as e: 4964f44304bSSimon Glass self._DoTestFile('13_pack_inv_size_align.dts') 4974f44304bSSimon Glass self.assertIn("Node '/binman/u-boot': Size 0x5 (5) does not match " 4984f44304bSSimon Glass "align-size 0x4 (4)", str(e.exception)) 4994f44304bSSimon Glass 5004f44304bSSimon Glass def testPackOverlap(self): 5014f44304bSSimon Glass """Test that overlapping regions are detected""" 5024f44304bSSimon Glass with self.assertRaises(ValueError) as e: 5034f44304bSSimon Glass self._DoTestFile('14_pack_overlap.dts') 5044f44304bSSimon Glass self.assertIn("Node '/binman/u-boot-align': Position 0x3 (3) overlaps " 5054f44304bSSimon Glass "with previous entry '/binman/u-boot' ending at 0x4 (4)", 5064f44304bSSimon Glass str(e.exception)) 5074f44304bSSimon Glass 5084f44304bSSimon Glass def testPackEntryOverflow(self): 5094f44304bSSimon Glass """Test that entries that overflow their size are detected""" 5104f44304bSSimon Glass with self.assertRaises(ValueError) as e: 5114f44304bSSimon Glass self._DoTestFile('15_pack_overflow.dts') 5124f44304bSSimon Glass self.assertIn("Node '/binman/u-boot': Entry contents size is 0x4 (4) " 5134f44304bSSimon Glass "but entry size is 0x3 (3)", str(e.exception)) 5144f44304bSSimon Glass 5154f44304bSSimon Glass def testPackImageOverflow(self): 5164f44304bSSimon Glass """Test that entries which overflow the image size are detected""" 5174f44304bSSimon Glass with self.assertRaises(ValueError) as e: 5184f44304bSSimon Glass self._DoTestFile('16_pack_image_overflow.dts') 5194f44304bSSimon Glass self.assertIn("Image '/binman': contents size 0x4 (4) exceeds image " 5204f44304bSSimon Glass "size 0x3 (3)", str(e.exception)) 5214f44304bSSimon Glass 5224f44304bSSimon Glass def testPackImageSize(self): 5234f44304bSSimon Glass """Test that the image size can be set""" 5244f44304bSSimon Glass retcode = self._DoTestFile('17_pack_image_size.dts') 5254f44304bSSimon Glass self.assertEqual(0, retcode) 5264f44304bSSimon Glass self.assertIn('image', control.images) 5274f44304bSSimon Glass image = control.images['image'] 5284f44304bSSimon Glass self.assertEqual(7, image._size) 5294f44304bSSimon Glass 5304f44304bSSimon Glass def testPackImageSizeAlign(self): 5314f44304bSSimon Glass """Test that image size alignemnt works as expected""" 5324f44304bSSimon Glass retcode = self._DoTestFile('18_pack_image_align.dts') 5334f44304bSSimon Glass self.assertEqual(0, retcode) 5344f44304bSSimon Glass self.assertIn('image', control.images) 5354f44304bSSimon Glass image = control.images['image'] 5364f44304bSSimon Glass self.assertEqual(16, image._size) 5374f44304bSSimon Glass 5384f44304bSSimon Glass def testPackInvalidImageAlign(self): 5394f44304bSSimon Glass """Test that invalid image alignment is detected""" 5404f44304bSSimon Glass with self.assertRaises(ValueError) as e: 5414f44304bSSimon Glass self._DoTestFile('19_pack_inv_image_align.dts') 5424f44304bSSimon Glass self.assertIn("Image '/binman': Size 0x7 (7) does not match " 5434f44304bSSimon Glass "align-size 0x8 (8)", str(e.exception)) 5444f44304bSSimon Glass 5454f44304bSSimon Glass def testPackAlignPowerOf2(self): 5464f44304bSSimon Glass """Test that invalid image alignment is detected""" 5474f44304bSSimon Glass with self.assertRaises(ValueError) as e: 5484f44304bSSimon Glass self._DoTestFile('20_pack_inv_image_align_power2.dts') 5494f44304bSSimon Glass self.assertIn("Image '/binman': Alignment size 131 must be a power of " 5504f44304bSSimon Glass "two", str(e.exception)) 5514f44304bSSimon Glass 5524f44304bSSimon Glass def testImagePadByte(self): 5534f44304bSSimon Glass """Test that the image pad byte can be specified""" 5544f44304bSSimon Glass data = self._DoReadFile('21_image_pad.dts') 5554f44304bSSimon Glass self.assertEqual(U_BOOT_SPL_DATA + (chr(0xff) * 9) + U_BOOT_DATA, data) 5564f44304bSSimon Glass 5574f44304bSSimon Glass def testImageName(self): 5584f44304bSSimon Glass """Test that image files can be named""" 5594f44304bSSimon Glass retcode = self._DoTestFile('22_image_name.dts') 5604f44304bSSimon Glass self.assertEqual(0, retcode) 5614f44304bSSimon Glass image = control.images['image1'] 5624f44304bSSimon Glass fname = tools.GetOutputFilename('test-name') 5634f44304bSSimon Glass self.assertTrue(os.path.exists(fname)) 5644f44304bSSimon Glass 5654f44304bSSimon Glass image = control.images['image2'] 5664f44304bSSimon Glass fname = tools.GetOutputFilename('test-name.xx') 5674f44304bSSimon Glass self.assertTrue(os.path.exists(fname)) 5684f44304bSSimon Glass 5694f44304bSSimon Glass def testBlobFilename(self): 5704f44304bSSimon Glass """Test that generic blobs can be provided by filename""" 5714f44304bSSimon Glass data = self._DoReadFile('23_blob.dts') 5724f44304bSSimon Glass self.assertEqual(BLOB_DATA, data) 5734f44304bSSimon Glass 5744f44304bSSimon Glass def testPackSorted(self): 5754f44304bSSimon Glass """Test that entries can be sorted""" 5764f44304bSSimon Glass data = self._DoReadFile('24_sorted.dts') 5774f44304bSSimon Glass self.assertEqual(chr(0) * 5 + U_BOOT_SPL_DATA + chr(0) * 2 + 5784f44304bSSimon Glass U_BOOT_DATA, data) 5794f44304bSSimon Glass 5804f44304bSSimon Glass def testPackZeroPosition(self): 5814f44304bSSimon Glass """Test that an entry at position 0 is not given a new position""" 5824f44304bSSimon Glass with self.assertRaises(ValueError) as e: 5834f44304bSSimon Glass self._DoTestFile('25_pack_zero_size.dts') 5844f44304bSSimon Glass self.assertIn("Node '/binman/u-boot-spl': Position 0x0 (0) overlaps " 5854f44304bSSimon Glass "with previous entry '/binman/u-boot' ending at 0x4 (4)", 5864f44304bSSimon Glass str(e.exception)) 5874f44304bSSimon Glass 5884f44304bSSimon Glass def testPackUbootDtb(self): 5894f44304bSSimon Glass """Test that a device tree can be added to U-Boot""" 5904f44304bSSimon Glass data = self._DoReadFile('26_pack_u_boot_dtb.dts') 5914f44304bSSimon Glass self.assertEqual(U_BOOT_NODTB_DATA + U_BOOT_DTB_DATA, data) 592e0ff8551SSimon Glass 593e0ff8551SSimon Glass def testPackX86RomNoSize(self): 594e0ff8551SSimon Glass """Test that the end-at-4gb property requires a size property""" 595e0ff8551SSimon Glass with self.assertRaises(ValueError) as e: 596e0ff8551SSimon Glass self._DoTestFile('27_pack_4gb_no_size.dts') 597e0ff8551SSimon Glass self.assertIn("Image '/binman': Image size must be provided when " 598e0ff8551SSimon Glass "using end-at-4gb", str(e.exception)) 599e0ff8551SSimon Glass 600e0ff8551SSimon Glass def testPackX86RomOutside(self): 601e0ff8551SSimon Glass """Test that the end-at-4gb property checks for position boundaries""" 602e0ff8551SSimon Glass with self.assertRaises(ValueError) as e: 603e0ff8551SSimon Glass self._DoTestFile('28_pack_4gb_outside.dts') 604e0ff8551SSimon Glass self.assertIn("Node '/binman/u-boot': Position 0x0 (0) is outside " 605e0ff8551SSimon Glass "the image starting at 0xfffffff0 (4294967280)", 606e0ff8551SSimon Glass str(e.exception)) 607e0ff8551SSimon Glass 608e0ff8551SSimon Glass def testPackX86Rom(self): 609e0ff8551SSimon Glass """Test that a basic x86 ROM can be created""" 610e0ff8551SSimon Glass data = self._DoReadFile('29_x86-rom.dts') 611e0ff8551SSimon Glass self.assertEqual(U_BOOT_DATA + chr(0) * 3 + U_BOOT_SPL_DATA + 612e0ff8551SSimon Glass chr(0) * 6, data) 613e0ff8551SSimon Glass 614e0ff8551SSimon Glass def testPackX86RomMeNoDesc(self): 615e0ff8551SSimon Glass """Test that an invalid Intel descriptor entry is detected""" 616e0ff8551SSimon Glass TestFunctional._MakeInputFile('descriptor.bin', '') 617e0ff8551SSimon Glass with self.assertRaises(ValueError) as e: 618e0ff8551SSimon Glass self._DoTestFile('31_x86-rom-me.dts') 619e0ff8551SSimon Glass self.assertIn("Node '/binman/intel-descriptor': Cannot find FD " 620e0ff8551SSimon Glass "signature", str(e.exception)) 621e0ff8551SSimon Glass 622e0ff8551SSimon Glass def testPackX86RomBadDesc(self): 623e0ff8551SSimon Glass """Test that the Intel requires a descriptor entry""" 624e0ff8551SSimon Glass with self.assertRaises(ValueError) as e: 625e0ff8551SSimon Glass self._DoTestFile('30_x86-rom-me-no-desc.dts') 626e0ff8551SSimon Glass self.assertIn("Node '/binman/intel-me': No position set with " 627e0ff8551SSimon Glass "pos-unset: should another entry provide this correct " 628e0ff8551SSimon Glass "position?", str(e.exception)) 629e0ff8551SSimon Glass 630e0ff8551SSimon Glass def testPackX86RomMe(self): 631e0ff8551SSimon Glass """Test that an x86 ROM with an ME region can be created""" 632e0ff8551SSimon Glass data = self._DoReadFile('31_x86-rom-me.dts') 633e0ff8551SSimon Glass self.assertEqual(ME_DATA, data[0x1000:0x1000 + len(ME_DATA)]) 634e0ff8551SSimon Glass 635e0ff8551SSimon Glass def testPackVga(self): 636e0ff8551SSimon Glass """Test that an image with a VGA binary can be created""" 637e0ff8551SSimon Glass data = self._DoReadFile('32_intel-vga.dts') 638e0ff8551SSimon Glass self.assertEqual(VGA_DATA, data[:len(VGA_DATA)]) 639e0ff8551SSimon Glass 640e0ff8551SSimon Glass def testPackStart16(self): 641e0ff8551SSimon Glass """Test that an image with an x86 start16 region can be created""" 642e0ff8551SSimon Glass data = self._DoReadFile('33_x86-start16.dts') 643e0ff8551SSimon Glass self.assertEqual(X86_START16_DATA, data[:len(X86_START16_DATA)]) 644e0ff8551SSimon Glass 645e0ff8551SSimon Glass def testPackUbootMicrocode(self): 646e0ff8551SSimon Glass """Test that x86 microcode can be handled correctly 647e0ff8551SSimon Glass 648e0ff8551SSimon Glass We expect to see the following in the image, in order: 649e0ff8551SSimon Glass u-boot-nodtb.bin with a microcode pointer inserted at the correct 650e0ff8551SSimon Glass place 651e0ff8551SSimon Glass u-boot.dtb with the microcode removed 652e0ff8551SSimon Glass the microcode 653e0ff8551SSimon Glass """ 654e0ff8551SSimon Glass data = self._DoReadFile('34_x86_ucode.dts', True) 655e0ff8551SSimon Glass 656e0ff8551SSimon Glass # Now check the device tree has no microcode 657e0ff8551SSimon Glass second = data[len(U_BOOT_NODTB_DATA):] 658e0ff8551SSimon Glass fname = tools.GetOutputFilename('test.dtb') 659e0ff8551SSimon Glass with open(fname, 'wb') as fd: 660e0ff8551SSimon Glass fd.write(second) 661ec3f378aSSimon Glass dtb = fdt.FdtScan(fname) 662ec3f378aSSimon Glass ucode = dtb.GetNode('/microcode') 663e0ff8551SSimon Glass self.assertTrue(ucode) 664e0ff8551SSimon Glass for node in ucode.subnodes: 665e0ff8551SSimon Glass self.assertFalse(node.props.get('data')) 666e0ff8551SSimon Glass 667e0ff8551SSimon Glass fdt_len = self.GetFdtLen(second) 668e0ff8551SSimon Glass third = second[fdt_len:] 669e0ff8551SSimon Glass 670e0ff8551SSimon Glass # Check that the microcode appears immediately after the Fdt 671e0ff8551SSimon Glass # This matches the concatenation of the data properties in 672e0ff8551SSimon Glass # the /microcode/update@xxx nodes in x86_ucode.dts. 673e0ff8551SSimon Glass ucode_data = struct.pack('>4L', 0x12345678, 0x12345679, 0xabcd0000, 674e0ff8551SSimon Glass 0x78235609) 675e0ff8551SSimon Glass self.assertEqual(ucode_data, third[:len(ucode_data)]) 676e0ff8551SSimon Glass ucode_pos = len(U_BOOT_NODTB_DATA) + fdt_len 677e0ff8551SSimon Glass 678e0ff8551SSimon Glass # Check that the microcode pointer was inserted. It should match the 679e0ff8551SSimon Glass # expected position and size 680e0ff8551SSimon Glass pos_and_size = struct.pack('<2L', 0xfffffe00 + ucode_pos, 681e0ff8551SSimon Glass len(ucode_data)) 682e0ff8551SSimon Glass first = data[:len(U_BOOT_NODTB_DATA)] 683e0ff8551SSimon Glass self.assertEqual('nodtb with microcode' + pos_and_size + 684e0ff8551SSimon Glass ' somewhere in here', first) 685e0ff8551SSimon Glass 686160a7664SSimon Glass def _RunPackUbootSingleMicrocode(self): 687e0ff8551SSimon Glass """Test that x86 microcode can be handled correctly 688e0ff8551SSimon Glass 689e0ff8551SSimon Glass We expect to see the following in the image, in order: 690e0ff8551SSimon Glass u-boot-nodtb.bin with a microcode pointer inserted at the correct 691e0ff8551SSimon Glass place 692e0ff8551SSimon Glass u-boot.dtb with the microcode 693e0ff8551SSimon Glass an empty microcode region 694e0ff8551SSimon Glass """ 695e0ff8551SSimon Glass # We need the libfdt library to run this test since only that allows 696e0ff8551SSimon Glass # finding the offset of a property. This is required by 697e0ff8551SSimon Glass # Entry_u_boot_dtb_with_ucode.ObtainContents(). 698e0ff8551SSimon Glass data = self._DoReadFile('35_x86_single_ucode.dts', True) 699e0ff8551SSimon Glass 700e0ff8551SSimon Glass second = data[len(U_BOOT_NODTB_DATA):] 701e0ff8551SSimon Glass 702e0ff8551SSimon Glass fdt_len = self.GetFdtLen(second) 703e0ff8551SSimon Glass third = second[fdt_len:] 704e0ff8551SSimon Glass second = second[:fdt_len] 705e0ff8551SSimon Glass 706e0ff8551SSimon Glass ucode_data = struct.pack('>2L', 0x12345678, 0x12345679) 707e0ff8551SSimon Glass self.assertIn(ucode_data, second) 708e0ff8551SSimon Glass ucode_pos = second.find(ucode_data) + len(U_BOOT_NODTB_DATA) 709e0ff8551SSimon Glass 710e0ff8551SSimon Glass # Check that the microcode pointer was inserted. It should match the 711e0ff8551SSimon Glass # expected position and size 712e0ff8551SSimon Glass pos_and_size = struct.pack('<2L', 0xfffffe00 + ucode_pos, 713e0ff8551SSimon Glass len(ucode_data)) 714e0ff8551SSimon Glass first = data[:len(U_BOOT_NODTB_DATA)] 715e0ff8551SSimon Glass self.assertEqual('nodtb with microcode' + pos_and_size + 716e0ff8551SSimon Glass ' somewhere in here', first) 717c49deb83SSimon Glass 71875db0860SSimon Glass def testPackUbootSingleMicrocode(self): 71975db0860SSimon Glass """Test that x86 microcode can be handled correctly with fdt_normal. 72075db0860SSimon Glass """ 721160a7664SSimon Glass self._RunPackUbootSingleMicrocode() 72275db0860SSimon Glass 723c49deb83SSimon Glass def testUBootImg(self): 724c49deb83SSimon Glass """Test that u-boot.img can be put in a file""" 725c49deb83SSimon Glass data = self._DoReadFile('36_u_boot_img.dts') 726c49deb83SSimon Glass self.assertEqual(U_BOOT_IMG_DATA, data) 72775db0860SSimon Glass 72875db0860SSimon Glass def testNoMicrocode(self): 72975db0860SSimon Glass """Test that a missing microcode region is detected""" 73075db0860SSimon Glass with self.assertRaises(ValueError) as e: 73175db0860SSimon Glass self._DoReadFile('37_x86_no_ucode.dts', True) 73275db0860SSimon Glass self.assertIn("Node '/binman/u-boot-dtb-with-ucode': No /microcode " 73375db0860SSimon Glass "node found in ", str(e.exception)) 73475db0860SSimon Glass 73575db0860SSimon Glass def testMicrocodeWithoutNode(self): 73675db0860SSimon Glass """Test that a missing u-boot-dtb-with-ucode node is detected""" 73775db0860SSimon Glass with self.assertRaises(ValueError) as e: 73875db0860SSimon Glass self._DoReadFile('38_x86_ucode_missing_node.dts', True) 73975db0860SSimon Glass self.assertIn("Node '/binman/u-boot-with-ucode-ptr': Cannot find " 74075db0860SSimon Glass "microcode region u-boot-dtb-with-ucode", str(e.exception)) 74175db0860SSimon Glass 74275db0860SSimon Glass def testMicrocodeWithoutNode2(self): 74375db0860SSimon Glass """Test that a missing u-boot-ucode node is detected""" 74475db0860SSimon Glass with self.assertRaises(ValueError) as e: 74575db0860SSimon Glass self._DoReadFile('39_x86_ucode_missing_node2.dts', True) 74675db0860SSimon Glass self.assertIn("Node '/binman/u-boot-with-ucode-ptr': Cannot find " 74775db0860SSimon Glass "microcode region u-boot-ucode", str(e.exception)) 74875db0860SSimon Glass 74975db0860SSimon Glass def testMicrocodeWithoutPtrInElf(self): 75075db0860SSimon Glass """Test that a U-Boot binary without the microcode symbol is detected""" 75175db0860SSimon Glass # ELF file without a '_dt_ucode_base_size' symbol 75275db0860SSimon Glass try: 75375db0860SSimon Glass with open(self.TestFile('u_boot_no_ucode_ptr')) as fd: 75475db0860SSimon Glass TestFunctional._MakeInputFile('u-boot', fd.read()) 75575db0860SSimon Glass 75675db0860SSimon Glass with self.assertRaises(ValueError) as e: 757160a7664SSimon Glass self._RunPackUbootSingleMicrocode() 75875db0860SSimon Glass self.assertIn("Node '/binman/u-boot-with-ucode-ptr': Cannot locate " 75975db0860SSimon Glass "_dt_ucode_base_size symbol in u-boot", str(e.exception)) 76075db0860SSimon Glass 76175db0860SSimon Glass finally: 76275db0860SSimon Glass # Put the original file back 76375db0860SSimon Glass with open(self.TestFile('u_boot_ucode_ptr')) as fd: 76475db0860SSimon Glass TestFunctional._MakeInputFile('u-boot', fd.read()) 76575db0860SSimon Glass 76675db0860SSimon Glass def testMicrocodeNotInImage(self): 76775db0860SSimon Glass """Test that microcode must be placed within the image""" 76875db0860SSimon Glass with self.assertRaises(ValueError) as e: 76975db0860SSimon Glass self._DoReadFile('40_x86_ucode_not_in_image.dts', True) 77075db0860SSimon Glass self.assertIn("Node '/binman/u-boot-with-ucode-ptr': Microcode " 77175db0860SSimon Glass "pointer _dt_ucode_base_size at fffffe14 is outside the " 77275db0860SSimon Glass "image ranging from 00000000 to 0000002e", str(e.exception)) 77375db0860SSimon Glass 77475db0860SSimon Glass def testWithoutMicrocode(self): 77575db0860SSimon Glass """Test that we can cope with an image without microcode (e.g. qemu)""" 77675db0860SSimon Glass with open(self.TestFile('u_boot_no_ucode_ptr')) as fd: 77775db0860SSimon Glass TestFunctional._MakeInputFile('u-boot', fd.read()) 77875db0860SSimon Glass data, dtb = self._DoReadFileDtb('44_x86_optional_ucode.dts', True) 77975db0860SSimon Glass 78075db0860SSimon Glass # Now check the device tree has no microcode 78175db0860SSimon Glass self.assertEqual(U_BOOT_NODTB_DATA, data[:len(U_BOOT_NODTB_DATA)]) 78275db0860SSimon Glass second = data[len(U_BOOT_NODTB_DATA):] 78375db0860SSimon Glass 78475db0860SSimon Glass fdt_len = self.GetFdtLen(second) 78575db0860SSimon Glass self.assertEqual(dtb, second[:fdt_len]) 78675db0860SSimon Glass 78775db0860SSimon Glass used_len = len(U_BOOT_NODTB_DATA) + fdt_len 78875db0860SSimon Glass third = data[used_len:] 78975db0860SSimon Glass self.assertEqual(chr(0) * (0x200 - used_len), third) 79075db0860SSimon Glass 79175db0860SSimon Glass def testUnknownPosSize(self): 79275db0860SSimon Glass """Test that microcode must be placed within the image""" 79375db0860SSimon Glass with self.assertRaises(ValueError) as e: 79475db0860SSimon Glass self._DoReadFile('41_unknown_pos_size.dts', True) 79575db0860SSimon Glass self.assertIn("Image '/binman': Unable to set pos/size for unknown " 79675db0860SSimon Glass "entry 'invalid-entry'", str(e.exception)) 797da229090SSimon Glass 798da229090SSimon Glass def testPackFsp(self): 799da229090SSimon Glass """Test that an image with a FSP binary can be created""" 800da229090SSimon Glass data = self._DoReadFile('42_intel-fsp.dts') 801da229090SSimon Glass self.assertEqual(FSP_DATA, data[:len(FSP_DATA)]) 802da229090SSimon Glass 803da229090SSimon Glass def testPackCmc(self): 804da229090SSimon Glass """Test that an image with a FSP binary can be created""" 805da229090SSimon Glass data = self._DoReadFile('43_intel-cmc.dts') 806da229090SSimon Glass self.assertEqual(CMC_DATA, data[:len(CMC_DATA)]) 807