xref: /rk3399_rockchip-uboot/tools/binman/func_test.py (revision e0ff85513858246e5378e4e3676ef6128452c4f6)
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
244f44304bSSimon Glassimport fdt_select
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'
394f44304bSSimon Glass
404f44304bSSimon Glassclass TestFunctional(unittest.TestCase):
414f44304bSSimon Glass    """Functional tests for binman
424f44304bSSimon Glass
434f44304bSSimon Glass    Most of these use a sample .dts file to build an image and then check
444f44304bSSimon Glass    that it looks correct. The sample files are in the test/ subdirectory
454f44304bSSimon Glass    and are numbered.
464f44304bSSimon Glass
474f44304bSSimon Glass    For each entry type a very small test file is created using fixed
484f44304bSSimon Glass    string contents. This makes it easy to test that things look right, and
494f44304bSSimon Glass    debug problems.
504f44304bSSimon Glass
514f44304bSSimon Glass    In some cases a 'real' file must be used - these are also supplied in
524f44304bSSimon Glass    the test/ diurectory.
534f44304bSSimon Glass    """
544f44304bSSimon Glass    @classmethod
554f44304bSSimon Glass    def setUpClass(self):
564f44304bSSimon Glass        # Handle the case where argv[0] is 'python'
574f44304bSSimon Glass        self._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
584f44304bSSimon Glass        self._binman_pathname = os.path.join(self._binman_dir, 'binman')
594f44304bSSimon Glass
604f44304bSSimon Glass        # Create a temporary directory for input files
614f44304bSSimon Glass        self._indir = tempfile.mkdtemp(prefix='binmant.')
624f44304bSSimon Glass
634f44304bSSimon Glass        # Create some test files
644f44304bSSimon Glass        TestFunctional._MakeInputFile('u-boot.bin', U_BOOT_DATA)
654f44304bSSimon Glass        TestFunctional._MakeInputFile('u-boot.img', U_BOOT_IMG_DATA)
664f44304bSSimon Glass        TestFunctional._MakeInputFile('spl/u-boot-spl.bin', U_BOOT_SPL_DATA)
674f44304bSSimon Glass        TestFunctional._MakeInputFile('blobfile', BLOB_DATA)
68*e0ff8551SSimon Glass        TestFunctional._MakeInputFile('me.bin', ME_DATA)
69*e0ff8551SSimon Glass        TestFunctional._MakeInputFile('vga.bin', VGA_DATA)
704f44304bSSimon Glass        TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA)
71*e0ff8551SSimon Glass        TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA)
724f44304bSSimon Glass        TestFunctional._MakeInputFile('u-boot-nodtb.bin', U_BOOT_NODTB_DATA)
734f44304bSSimon Glass        self._output_setup = False
744f44304bSSimon Glass
75*e0ff8551SSimon Glass        # ELF file with a '_dt_ucode_base_size' symbol
76*e0ff8551SSimon Glass        with open(self.TestFile('u_boot_ucode_ptr')) as fd:
77*e0ff8551SSimon Glass            TestFunctional._MakeInputFile('u-boot', fd.read())
78*e0ff8551SSimon Glass
79*e0ff8551SSimon Glass        # Intel flash descriptor file
80*e0ff8551SSimon Glass        with open(self.TestFile('descriptor.bin')) as fd:
81*e0ff8551SSimon Glass            TestFunctional._MakeInputFile('descriptor.bin', fd.read())
82*e0ff8551SSimon Glass
834f44304bSSimon Glass    @classmethod
844f44304bSSimon Glass    def tearDownClass(self):
854f44304bSSimon Glass        """Remove the temporary input directory and its contents"""
864f44304bSSimon Glass        if self._indir:
874f44304bSSimon Glass            shutil.rmtree(self._indir)
884f44304bSSimon Glass        self._indir = None
894f44304bSSimon Glass
904f44304bSSimon Glass    def setUp(self):
914f44304bSSimon Glass        # Enable this to turn on debugging output
924f44304bSSimon Glass        # tout.Init(tout.DEBUG)
934f44304bSSimon Glass        command.test_result = None
944f44304bSSimon Glass
954f44304bSSimon Glass    def tearDown(self):
964f44304bSSimon Glass        """Remove the temporary output directory"""
974f44304bSSimon Glass        tools._FinaliseForTest()
984f44304bSSimon Glass
994f44304bSSimon Glass    def _RunBinman(self, *args, **kwargs):
1004f44304bSSimon Glass        """Run binman using the command line
1014f44304bSSimon Glass
1024f44304bSSimon Glass        Args:
1034f44304bSSimon Glass            Arguments to pass, as a list of strings
1044f44304bSSimon Glass            kwargs: Arguments to pass to Command.RunPipe()
1054f44304bSSimon Glass        """
1064f44304bSSimon Glass        result = command.RunPipe([[self._binman_pathname] + list(args)],
1074f44304bSSimon Glass                capture=True, capture_stderr=True, raise_on_error=False)
1084f44304bSSimon Glass        if result.return_code and kwargs.get('raise_on_error', True):
1094f44304bSSimon Glass            raise Exception("Error running '%s': %s" % (' '.join(args),
1104f44304bSSimon Glass                            result.stdout + result.stderr))
1114f44304bSSimon Glass        return result
1124f44304bSSimon Glass
1134f44304bSSimon Glass    def _DoBinman(self, *args):
1144f44304bSSimon Glass        """Run binman using directly (in the same process)
1154f44304bSSimon Glass
1164f44304bSSimon Glass        Args:
1174f44304bSSimon Glass            Arguments to pass, as a list of strings
1184f44304bSSimon Glass        Returns:
1194f44304bSSimon Glass            Return value (0 for success)
1204f44304bSSimon Glass        """
1214f44304bSSimon Glass        (options, args) = cmdline.ParseArgs(list(args))
1224f44304bSSimon Glass        options.pager = 'binman-invalid-pager'
1234f44304bSSimon Glass        options.build_dir = self._indir
1244f44304bSSimon Glass
1254f44304bSSimon Glass        # For testing, you can force an increase in verbosity here
1264f44304bSSimon Glass        # options.verbosity = tout.DEBUG
1274f44304bSSimon Glass        return control.Binman(options, args)
1284f44304bSSimon Glass
1294f44304bSSimon Glass    def _DoTestFile(self, fname):
1304f44304bSSimon Glass        """Run binman with a given test file
1314f44304bSSimon Glass
1324f44304bSSimon Glass        Args:
1334f44304bSSimon Glass            fname: Device tree source filename to use (e.g. 05_simple.dts)
1344f44304bSSimon Glass        """
1354f44304bSSimon Glass        return self._DoBinman('-p', '-I', self._indir,
1364f44304bSSimon Glass                              '-d', self.TestFile(fname))
1374f44304bSSimon Glass
1384f44304bSSimon Glass    def _SetupDtb(self, fname, outfile='u-boot.dtb'):
139*e0ff8551SSimon Glass        """Set up a new test device-tree file
140*e0ff8551SSimon Glass
141*e0ff8551SSimon Glass        The given file is compiled and set up as the device tree to be used
142*e0ff8551SSimon Glass        for ths test.
143*e0ff8551SSimon Glass
144*e0ff8551SSimon Glass        Args:
145*e0ff8551SSimon Glass            fname: Filename of .dts file to read
146*e0ff8551SSimon Glass            outfile: Output filename for compiled device tree binary
147*e0ff8551SSimon Glass
148*e0ff8551SSimon Glass        Returns:
149*e0ff8551SSimon Glass            Contents of device tree binary
150*e0ff8551SSimon Glass        """
1514f44304bSSimon Glass        if not self._output_setup:
1524f44304bSSimon Glass            tools.PrepareOutputDir(self._indir, True)
1534f44304bSSimon Glass            self._output_setup = True
1544f44304bSSimon Glass        dtb = fdt_util.EnsureCompiled(self.TestFile(fname))
1554f44304bSSimon Glass        with open(dtb) as fd:
1564f44304bSSimon Glass            data = fd.read()
1574f44304bSSimon Glass            TestFunctional._MakeInputFile(outfile, data)
158*e0ff8551SSimon Glass            return data
1594f44304bSSimon Glass
160*e0ff8551SSimon Glass    def _DoReadFileDtb(self, fname, use_real_dtb=False):
1614f44304bSSimon Glass        """Run binman and return the resulting image
1624f44304bSSimon Glass
1634f44304bSSimon Glass        This runs binman with a given test file and then reads the resulting
1644f44304bSSimon Glass        output file. It is a shortcut function since most tests need to do
1654f44304bSSimon Glass        these steps.
1664f44304bSSimon Glass
1674f44304bSSimon Glass        Raises an assertion failure if binman returns a non-zero exit code.
1684f44304bSSimon Glass
1694f44304bSSimon Glass        Args:
1704f44304bSSimon Glass            fname: Device tree source filename to use (e.g. 05_simple.dts)
1714f44304bSSimon Glass            use_real_dtb: True to use the test file as the contents of
1724f44304bSSimon Glass                the u-boot-dtb entry. Normally this is not needed and the
1734f44304bSSimon Glass                test contents (the U_BOOT_DTB_DATA string) can be used.
1744f44304bSSimon Glass                But in some test we need the real contents.
175*e0ff8551SSimon Glass
176*e0ff8551SSimon Glass        Returns:
177*e0ff8551SSimon Glass            Tuple:
178*e0ff8551SSimon Glass                Resulting image contents
179*e0ff8551SSimon Glass                Device tree contents
1804f44304bSSimon Glass        """
181*e0ff8551SSimon Glass        dtb_data = None
1824f44304bSSimon Glass        # Use the compiled test file as the u-boot-dtb input
1834f44304bSSimon Glass        if use_real_dtb:
184*e0ff8551SSimon Glass            dtb_data = self._SetupDtb(fname)
1854f44304bSSimon Glass
1864f44304bSSimon Glass        try:
1874f44304bSSimon Glass            retcode = self._DoTestFile(fname)
1884f44304bSSimon Glass            self.assertEqual(0, retcode)
1894f44304bSSimon Glass
1904f44304bSSimon Glass            # Find the (only) image, read it and return its contents
1914f44304bSSimon Glass            image = control.images['image']
1924f44304bSSimon Glass            fname = tools.GetOutputFilename('image.bin')
1934f44304bSSimon Glass            self.assertTrue(os.path.exists(fname))
1944f44304bSSimon Glass            with open(fname) as fd:
195*e0ff8551SSimon Glass                return fd.read(), dtb_data
1964f44304bSSimon Glass        finally:
1974f44304bSSimon Glass            # Put the test file back
1984f44304bSSimon Glass            if use_real_dtb:
1994f44304bSSimon Glass                TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA)
2004f44304bSSimon Glass
201*e0ff8551SSimon Glass    def _DoReadFile(self, fname, use_real_dtb=False):
202*e0ff8551SSimon Glass        """Helper function which discards the device-tree binary"""
203*e0ff8551SSimon Glass        return self._DoReadFileDtb(fname, use_real_dtb)[0]
204*e0ff8551SSimon Glass
2054f44304bSSimon Glass    @classmethod
2064f44304bSSimon Glass    def _MakeInputFile(self, fname, contents):
2074f44304bSSimon Glass        """Create a new test input file, creating directories as needed
2084f44304bSSimon Glass
2094f44304bSSimon Glass        Args:
2104f44304bSSimon Glass            fname: Filenaem to create
2114f44304bSSimon Glass            contents: File contents to write in to the file
2124f44304bSSimon Glass        Returns:
2134f44304bSSimon Glass            Full pathname of file created
2144f44304bSSimon Glass        """
2154f44304bSSimon Glass        pathname = os.path.join(self._indir, fname)
2164f44304bSSimon Glass        dirname = os.path.dirname(pathname)
2174f44304bSSimon Glass        if dirname and not os.path.exists(dirname):
2184f44304bSSimon Glass            os.makedirs(dirname)
2194f44304bSSimon Glass        with open(pathname, 'wb') as fd:
2204f44304bSSimon Glass            fd.write(contents)
2214f44304bSSimon Glass        return pathname
2224f44304bSSimon Glass
2234f44304bSSimon Glass    @classmethod
2244f44304bSSimon Glass    def TestFile(self, fname):
2254f44304bSSimon Glass        return os.path.join(self._binman_dir, 'test', fname)
2264f44304bSSimon Glass
2274f44304bSSimon Glass    def AssertInList(self, grep_list, target):
2284f44304bSSimon Glass        """Assert that at least one of a list of things is in a target
2294f44304bSSimon Glass
2304f44304bSSimon Glass        Args:
2314f44304bSSimon Glass            grep_list: List of strings to check
2324f44304bSSimon Glass            target: Target string
2334f44304bSSimon Glass        """
2344f44304bSSimon Glass        for grep in grep_list:
2354f44304bSSimon Glass            if grep in target:
2364f44304bSSimon Glass                return
2374f44304bSSimon Glass        self.fail("Error: '%' not found in '%s'" % (grep_list, target))
2384f44304bSSimon Glass
2394f44304bSSimon Glass    def CheckNoGaps(self, entries):
2404f44304bSSimon Glass        """Check that all entries fit together without gaps
2414f44304bSSimon Glass
2424f44304bSSimon Glass        Args:
2434f44304bSSimon Glass            entries: List of entries to check
2444f44304bSSimon Glass        """
2454f44304bSSimon Glass        pos = 0
2464f44304bSSimon Glass        for entry in entries.values():
2474f44304bSSimon Glass            self.assertEqual(pos, entry.pos)
2484f44304bSSimon Glass            pos += entry.size
2494f44304bSSimon Glass
250*e0ff8551SSimon Glass    def GetFdtLen(self, dtb):
251*e0ff8551SSimon Glass        """Get the totalsize field from a device tree binary
252*e0ff8551SSimon Glass
253*e0ff8551SSimon Glass        Args:
254*e0ff8551SSimon Glass            dtb: Device tree binary contents
255*e0ff8551SSimon Glass
256*e0ff8551SSimon Glass        Returns:
257*e0ff8551SSimon Glass            Total size of device tree binary, from the header
258*e0ff8551SSimon Glass        """
259*e0ff8551SSimon Glass        return struct.unpack('>L', dtb[4:8])[0]
260*e0ff8551SSimon Glass
2614f44304bSSimon Glass    def testRun(self):
2624f44304bSSimon Glass        """Test a basic run with valid args"""
2634f44304bSSimon Glass        result = self._RunBinman('-h')
2644f44304bSSimon Glass
2654f44304bSSimon Glass    def testFullHelp(self):
2664f44304bSSimon Glass        """Test that the full help is displayed with -H"""
2674f44304bSSimon Glass        result = self._RunBinman('-H')
2684f44304bSSimon Glass        help_file = os.path.join(self._binman_dir, 'README')
2694f44304bSSimon Glass        self.assertEqual(len(result.stdout), os.path.getsize(help_file))
2704f44304bSSimon Glass        self.assertEqual(0, len(result.stderr))
2714f44304bSSimon Glass        self.assertEqual(0, result.return_code)
2724f44304bSSimon Glass
2734f44304bSSimon Glass    def testFullHelpInternal(self):
2744f44304bSSimon Glass        """Test that the full help is displayed with -H"""
2754f44304bSSimon Glass        try:
2764f44304bSSimon Glass            command.test_result = command.CommandResult()
2774f44304bSSimon Glass            result = self._DoBinman('-H')
2784f44304bSSimon Glass            help_file = os.path.join(self._binman_dir, 'README')
2794f44304bSSimon Glass        finally:
2804f44304bSSimon Glass            command.test_result = None
2814f44304bSSimon Glass
2824f44304bSSimon Glass    def testHelp(self):
2834f44304bSSimon Glass        """Test that the basic help is displayed with -h"""
2844f44304bSSimon Glass        result = self._RunBinman('-h')
2854f44304bSSimon Glass        self.assertTrue(len(result.stdout) > 200)
2864f44304bSSimon Glass        self.assertEqual(0, len(result.stderr))
2874f44304bSSimon Glass        self.assertEqual(0, result.return_code)
2884f44304bSSimon Glass
2894f44304bSSimon Glass    # Not yet available.
2904f44304bSSimon Glass    def testBoard(self):
2914f44304bSSimon Glass        """Test that we can run it with a specific board"""
2924f44304bSSimon Glass        self._SetupDtb('05_simple.dts', 'sandbox/u-boot.dtb')
2934f44304bSSimon Glass        TestFunctional._MakeInputFile('sandbox/u-boot.bin', U_BOOT_DATA)
2944f44304bSSimon Glass        result = self._DoBinman('-b', 'sandbox')
2954f44304bSSimon Glass        self.assertEqual(0, result)
2964f44304bSSimon Glass
2974f44304bSSimon Glass    def testNeedBoard(self):
2984f44304bSSimon Glass        """Test that we get an error when no board ius supplied"""
2994f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
3004f44304bSSimon Glass            result = self._DoBinman()
3014f44304bSSimon Glass        self.assertIn("Must provide a board to process (use -b <board>)",
3024f44304bSSimon Glass                str(e.exception))
3034f44304bSSimon Glass
3044f44304bSSimon Glass    def testMissingDt(self):
3054f44304bSSimon Glass        """Test that an invalid device tree file generates an error"""
3064f44304bSSimon Glass        with self.assertRaises(Exception) as e:
3074f44304bSSimon Glass            self._RunBinman('-d', 'missing_file')
3084f44304bSSimon Glass        # We get one error from libfdt, and a different one from fdtget.
3094f44304bSSimon Glass        self.AssertInList(["Couldn't open blob from 'missing_file'",
3104f44304bSSimon Glass                           'No such file or directory'], str(e.exception))
3114f44304bSSimon Glass
3124f44304bSSimon Glass    def testBrokenDt(self):
3134f44304bSSimon Glass        """Test that an invalid device tree source file generates an error
3144f44304bSSimon Glass
3154f44304bSSimon Glass        Since this is a source file it should be compiled and the error
3164f44304bSSimon Glass        will come from the device-tree compiler (dtc).
3174f44304bSSimon Glass        """
3184f44304bSSimon Glass        with self.assertRaises(Exception) as e:
3194f44304bSSimon Glass            self._RunBinman('-d', self.TestFile('01_invalid.dts'))
3204f44304bSSimon Glass        self.assertIn("FATAL ERROR: Unable to parse input tree",
3214f44304bSSimon Glass                str(e.exception))
3224f44304bSSimon Glass
3234f44304bSSimon Glass    def testMissingNode(self):
3244f44304bSSimon Glass        """Test that a device tree without a 'binman' node generates an error"""
3254f44304bSSimon Glass        with self.assertRaises(Exception) as e:
3264f44304bSSimon Glass            self._DoBinman('-d', self.TestFile('02_missing_node.dts'))
3274f44304bSSimon Glass        self.assertIn("does not have a 'binman' node", str(e.exception))
3284f44304bSSimon Glass
3294f44304bSSimon Glass    def testEmpty(self):
3304f44304bSSimon Glass        """Test that an empty binman node works OK (i.e. does nothing)"""
3314f44304bSSimon Glass        result = self._RunBinman('-d', self.TestFile('03_empty.dts'))
3324f44304bSSimon Glass        self.assertEqual(0, len(result.stderr))
3334f44304bSSimon Glass        self.assertEqual(0, result.return_code)
3344f44304bSSimon Glass
3354f44304bSSimon Glass    def testInvalidEntry(self):
3364f44304bSSimon Glass        """Test that an invalid entry is flagged"""
3374f44304bSSimon Glass        with self.assertRaises(Exception) as e:
3384f44304bSSimon Glass            result = self._RunBinman('-d',
3394f44304bSSimon Glass                                     self.TestFile('04_invalid_entry.dts'))
3404f44304bSSimon Glass        #print e.exception
3414f44304bSSimon Glass        self.assertIn("Unknown entry type 'not-a-valid-type' in node "
3424f44304bSSimon Glass                "'/binman/not-a-valid-type'", str(e.exception))
3434f44304bSSimon Glass
3444f44304bSSimon Glass    def testSimple(self):
3454f44304bSSimon Glass        """Test a simple binman with a single file"""
3464f44304bSSimon Glass        data = self._DoReadFile('05_simple.dts')
3474f44304bSSimon Glass        self.assertEqual(U_BOOT_DATA, data)
3484f44304bSSimon Glass
3494f44304bSSimon Glass    def testDual(self):
3504f44304bSSimon Glass        """Test that we can handle creating two images
3514f44304bSSimon Glass
3524f44304bSSimon Glass        This also tests image padding.
3534f44304bSSimon Glass        """
3544f44304bSSimon Glass        retcode = self._DoTestFile('06_dual_image.dts')
3554f44304bSSimon Glass        self.assertEqual(0, retcode)
3564f44304bSSimon Glass
3574f44304bSSimon Glass        image = control.images['image1']
3584f44304bSSimon Glass        self.assertEqual(len(U_BOOT_DATA), image._size)
3594f44304bSSimon Glass        fname = tools.GetOutputFilename('image1.bin')
3604f44304bSSimon Glass        self.assertTrue(os.path.exists(fname))
3614f44304bSSimon Glass        with open(fname) as fd:
3624f44304bSSimon Glass            data = fd.read()
3634f44304bSSimon Glass            self.assertEqual(U_BOOT_DATA, data)
3644f44304bSSimon Glass
3654f44304bSSimon Glass        image = control.images['image2']
3664f44304bSSimon Glass        self.assertEqual(3 + len(U_BOOT_DATA) + 5, image._size)
3674f44304bSSimon Glass        fname = tools.GetOutputFilename('image2.bin')
3684f44304bSSimon Glass        self.assertTrue(os.path.exists(fname))
3694f44304bSSimon Glass        with open(fname) as fd:
3704f44304bSSimon Glass            data = fd.read()
3714f44304bSSimon Glass            self.assertEqual(U_BOOT_DATA, data[3:7])
3724f44304bSSimon Glass            self.assertEqual(chr(0) * 3, data[:3])
3734f44304bSSimon Glass            self.assertEqual(chr(0) * 5, data[7:])
3744f44304bSSimon Glass
3754f44304bSSimon Glass    def testBadAlign(self):
3764f44304bSSimon Glass        """Test that an invalid alignment value is detected"""
3774f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
3784f44304bSSimon Glass            self._DoTestFile('07_bad_align.dts')
3794f44304bSSimon Glass        self.assertIn("Node '/binman/u-boot': Alignment 23 must be a power "
3804f44304bSSimon Glass                      "of two", str(e.exception))
3814f44304bSSimon Glass
3824f44304bSSimon Glass    def testPackSimple(self):
3834f44304bSSimon Glass        """Test that packing works as expected"""
3844f44304bSSimon Glass        retcode = self._DoTestFile('08_pack.dts')
3854f44304bSSimon Glass        self.assertEqual(0, retcode)
3864f44304bSSimon Glass        self.assertIn('image', control.images)
3874f44304bSSimon Glass        image = control.images['image']
3884f44304bSSimon Glass        entries = image._entries
3894f44304bSSimon Glass        self.assertEqual(5, len(entries))
3904f44304bSSimon Glass
3914f44304bSSimon Glass        # First u-boot
3924f44304bSSimon Glass        self.assertIn('u-boot', entries)
3934f44304bSSimon Glass        entry = entries['u-boot']
3944f44304bSSimon Glass        self.assertEqual(0, entry.pos)
3954f44304bSSimon Glass        self.assertEqual(len(U_BOOT_DATA), entry.size)
3964f44304bSSimon Glass
3974f44304bSSimon Glass        # Second u-boot, aligned to 16-byte boundary
3984f44304bSSimon Glass        self.assertIn('u-boot-align', entries)
3994f44304bSSimon Glass        entry = entries['u-boot-align']
4004f44304bSSimon Glass        self.assertEqual(16, entry.pos)
4014f44304bSSimon Glass        self.assertEqual(len(U_BOOT_DATA), entry.size)
4024f44304bSSimon Glass
4034f44304bSSimon Glass        # Third u-boot, size 23 bytes
4044f44304bSSimon Glass        self.assertIn('u-boot-size', entries)
4054f44304bSSimon Glass        entry = entries['u-boot-size']
4064f44304bSSimon Glass        self.assertEqual(20, entry.pos)
4074f44304bSSimon Glass        self.assertEqual(len(U_BOOT_DATA), entry.contents_size)
4084f44304bSSimon Glass        self.assertEqual(23, entry.size)
4094f44304bSSimon Glass
4104f44304bSSimon Glass        # Fourth u-boot, placed immediate after the above
4114f44304bSSimon Glass        self.assertIn('u-boot-next', entries)
4124f44304bSSimon Glass        entry = entries['u-boot-next']
4134f44304bSSimon Glass        self.assertEqual(43, entry.pos)
4144f44304bSSimon Glass        self.assertEqual(len(U_BOOT_DATA), entry.size)
4154f44304bSSimon Glass
4164f44304bSSimon Glass        # Fifth u-boot, placed at a fixed position
4174f44304bSSimon Glass        self.assertIn('u-boot-fixed', entries)
4184f44304bSSimon Glass        entry = entries['u-boot-fixed']
4194f44304bSSimon Glass        self.assertEqual(61, entry.pos)
4204f44304bSSimon Glass        self.assertEqual(len(U_BOOT_DATA), entry.size)
4214f44304bSSimon Glass
4224f44304bSSimon Glass        self.assertEqual(65, image._size)
4234f44304bSSimon Glass
4244f44304bSSimon Glass    def testPackExtra(self):
4254f44304bSSimon Glass        """Test that extra packing feature works as expected"""
4264f44304bSSimon Glass        retcode = self._DoTestFile('09_pack_extra.dts')
4274f44304bSSimon Glass
4284f44304bSSimon Glass        self.assertEqual(0, retcode)
4294f44304bSSimon Glass        self.assertIn('image', control.images)
4304f44304bSSimon Glass        image = control.images['image']
4314f44304bSSimon Glass        entries = image._entries
4324f44304bSSimon Glass        self.assertEqual(5, len(entries))
4334f44304bSSimon Glass
4344f44304bSSimon Glass        # First u-boot with padding before and after
4354f44304bSSimon Glass        self.assertIn('u-boot', entries)
4364f44304bSSimon Glass        entry = entries['u-boot']
4374f44304bSSimon Glass        self.assertEqual(0, entry.pos)
4384f44304bSSimon Glass        self.assertEqual(3, entry.pad_before)
4394f44304bSSimon Glass        self.assertEqual(3 + 5 + len(U_BOOT_DATA), entry.size)
4404f44304bSSimon Glass
4414f44304bSSimon Glass        # Second u-boot has an aligned size, but it has no effect
4424f44304bSSimon Glass        self.assertIn('u-boot-align-size-nop', entries)
4434f44304bSSimon Glass        entry = entries['u-boot-align-size-nop']
4444f44304bSSimon Glass        self.assertEqual(12, entry.pos)
4454f44304bSSimon Glass        self.assertEqual(4, entry.size)
4464f44304bSSimon Glass
4474f44304bSSimon Glass        # Third u-boot has an aligned size too
4484f44304bSSimon Glass        self.assertIn('u-boot-align-size', entries)
4494f44304bSSimon Glass        entry = entries['u-boot-align-size']
4504f44304bSSimon Glass        self.assertEqual(16, entry.pos)
4514f44304bSSimon Glass        self.assertEqual(32, entry.size)
4524f44304bSSimon Glass
4534f44304bSSimon Glass        # Fourth u-boot has an aligned end
4544f44304bSSimon Glass        self.assertIn('u-boot-align-end', entries)
4554f44304bSSimon Glass        entry = entries['u-boot-align-end']
4564f44304bSSimon Glass        self.assertEqual(48, entry.pos)
4574f44304bSSimon Glass        self.assertEqual(16, entry.size)
4584f44304bSSimon Glass
4594f44304bSSimon Glass        # Fifth u-boot immediately afterwards
4604f44304bSSimon Glass        self.assertIn('u-boot-align-both', entries)
4614f44304bSSimon Glass        entry = entries['u-boot-align-both']
4624f44304bSSimon Glass        self.assertEqual(64, entry.pos)
4634f44304bSSimon Glass        self.assertEqual(64, entry.size)
4644f44304bSSimon Glass
4654f44304bSSimon Glass        self.CheckNoGaps(entries)
4664f44304bSSimon Glass        self.assertEqual(128, image._size)
4674f44304bSSimon Glass
4684f44304bSSimon Glass    def testPackAlignPowerOf2(self):
4694f44304bSSimon Glass        """Test that invalid entry alignment is detected"""
4704f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
4714f44304bSSimon Glass            self._DoTestFile('10_pack_align_power2.dts')
4724f44304bSSimon Glass        self.assertIn("Node '/binman/u-boot': Alignment 5 must be a power "
4734f44304bSSimon Glass                      "of two", str(e.exception))
4744f44304bSSimon Glass
4754f44304bSSimon Glass    def testPackAlignSizePowerOf2(self):
4764f44304bSSimon Glass        """Test that invalid entry size alignment is detected"""
4774f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
4784f44304bSSimon Glass            self._DoTestFile('11_pack_align_size_power2.dts')
4794f44304bSSimon Glass        self.assertIn("Node '/binman/u-boot': Alignment size 55 must be a "
4804f44304bSSimon Glass                      "power of two", str(e.exception))
4814f44304bSSimon Glass
4824f44304bSSimon Glass    def testPackInvalidAlign(self):
4834f44304bSSimon Glass        """Test detection of an position that does not match its alignment"""
4844f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
4854f44304bSSimon Glass            self._DoTestFile('12_pack_inv_align.dts')
4864f44304bSSimon Glass        self.assertIn("Node '/binman/u-boot': Position 0x5 (5) does not match "
4874f44304bSSimon Glass                      "align 0x4 (4)", str(e.exception))
4884f44304bSSimon Glass
4894f44304bSSimon Glass    def testPackInvalidSizeAlign(self):
4904f44304bSSimon Glass        """Test that invalid entry size alignment is detected"""
4914f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
4924f44304bSSimon Glass            self._DoTestFile('13_pack_inv_size_align.dts')
4934f44304bSSimon Glass        self.assertIn("Node '/binman/u-boot': Size 0x5 (5) does not match "
4944f44304bSSimon Glass                      "align-size 0x4 (4)", str(e.exception))
4954f44304bSSimon Glass
4964f44304bSSimon Glass    def testPackOverlap(self):
4974f44304bSSimon Glass        """Test that overlapping regions are detected"""
4984f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
4994f44304bSSimon Glass            self._DoTestFile('14_pack_overlap.dts')
5004f44304bSSimon Glass        self.assertIn("Node '/binman/u-boot-align': Position 0x3 (3) overlaps "
5014f44304bSSimon Glass                      "with previous entry '/binman/u-boot' ending at 0x4 (4)",
5024f44304bSSimon Glass                      str(e.exception))
5034f44304bSSimon Glass
5044f44304bSSimon Glass    def testPackEntryOverflow(self):
5054f44304bSSimon Glass        """Test that entries that overflow their size are detected"""
5064f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
5074f44304bSSimon Glass            self._DoTestFile('15_pack_overflow.dts')
5084f44304bSSimon Glass        self.assertIn("Node '/binman/u-boot': Entry contents size is 0x4 (4) "
5094f44304bSSimon Glass                      "but entry size is 0x3 (3)", str(e.exception))
5104f44304bSSimon Glass
5114f44304bSSimon Glass    def testPackImageOverflow(self):
5124f44304bSSimon Glass        """Test that entries which overflow the image size are detected"""
5134f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
5144f44304bSSimon Glass            self._DoTestFile('16_pack_image_overflow.dts')
5154f44304bSSimon Glass        self.assertIn("Image '/binman': contents size 0x4 (4) exceeds image "
5164f44304bSSimon Glass                      "size 0x3 (3)", str(e.exception))
5174f44304bSSimon Glass
5184f44304bSSimon Glass    def testPackImageSize(self):
5194f44304bSSimon Glass        """Test that the image size can be set"""
5204f44304bSSimon Glass        retcode = self._DoTestFile('17_pack_image_size.dts')
5214f44304bSSimon Glass        self.assertEqual(0, retcode)
5224f44304bSSimon Glass        self.assertIn('image', control.images)
5234f44304bSSimon Glass        image = control.images['image']
5244f44304bSSimon Glass        self.assertEqual(7, image._size)
5254f44304bSSimon Glass
5264f44304bSSimon Glass    def testPackImageSizeAlign(self):
5274f44304bSSimon Glass        """Test that image size alignemnt works as expected"""
5284f44304bSSimon Glass        retcode = self._DoTestFile('18_pack_image_align.dts')
5294f44304bSSimon Glass        self.assertEqual(0, retcode)
5304f44304bSSimon Glass        self.assertIn('image', control.images)
5314f44304bSSimon Glass        image = control.images['image']
5324f44304bSSimon Glass        self.assertEqual(16, image._size)
5334f44304bSSimon Glass
5344f44304bSSimon Glass    def testPackInvalidImageAlign(self):
5354f44304bSSimon Glass        """Test that invalid image alignment is detected"""
5364f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
5374f44304bSSimon Glass            self._DoTestFile('19_pack_inv_image_align.dts')
5384f44304bSSimon Glass        self.assertIn("Image '/binman': Size 0x7 (7) does not match "
5394f44304bSSimon Glass                      "align-size 0x8 (8)", str(e.exception))
5404f44304bSSimon Glass
5414f44304bSSimon Glass    def testPackAlignPowerOf2(self):
5424f44304bSSimon Glass        """Test that invalid image alignment is detected"""
5434f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
5444f44304bSSimon Glass            self._DoTestFile('20_pack_inv_image_align_power2.dts')
5454f44304bSSimon Glass        self.assertIn("Image '/binman': Alignment size 131 must be a power of "
5464f44304bSSimon Glass                      "two", str(e.exception))
5474f44304bSSimon Glass
5484f44304bSSimon Glass    def testImagePadByte(self):
5494f44304bSSimon Glass        """Test that the image pad byte can be specified"""
5504f44304bSSimon Glass        data = self._DoReadFile('21_image_pad.dts')
5514f44304bSSimon Glass        self.assertEqual(U_BOOT_SPL_DATA + (chr(0xff) * 9) + U_BOOT_DATA, data)
5524f44304bSSimon Glass
5534f44304bSSimon Glass    def testImageName(self):
5544f44304bSSimon Glass        """Test that image files can be named"""
5554f44304bSSimon Glass        retcode = self._DoTestFile('22_image_name.dts')
5564f44304bSSimon Glass        self.assertEqual(0, retcode)
5574f44304bSSimon Glass        image = control.images['image1']
5584f44304bSSimon Glass        fname = tools.GetOutputFilename('test-name')
5594f44304bSSimon Glass        self.assertTrue(os.path.exists(fname))
5604f44304bSSimon Glass
5614f44304bSSimon Glass        image = control.images['image2']
5624f44304bSSimon Glass        fname = tools.GetOutputFilename('test-name.xx')
5634f44304bSSimon Glass        self.assertTrue(os.path.exists(fname))
5644f44304bSSimon Glass
5654f44304bSSimon Glass    def testBlobFilename(self):
5664f44304bSSimon Glass        """Test that generic blobs can be provided by filename"""
5674f44304bSSimon Glass        data = self._DoReadFile('23_blob.dts')
5684f44304bSSimon Glass        self.assertEqual(BLOB_DATA, data)
5694f44304bSSimon Glass
5704f44304bSSimon Glass    def testPackSorted(self):
5714f44304bSSimon Glass        """Test that entries can be sorted"""
5724f44304bSSimon Glass        data = self._DoReadFile('24_sorted.dts')
5734f44304bSSimon Glass        self.assertEqual(chr(0) * 5 + U_BOOT_SPL_DATA + chr(0) * 2 +
5744f44304bSSimon Glass                         U_BOOT_DATA, data)
5754f44304bSSimon Glass
5764f44304bSSimon Glass    def testPackZeroPosition(self):
5774f44304bSSimon Glass        """Test that an entry at position 0 is not given a new position"""
5784f44304bSSimon Glass        with self.assertRaises(ValueError) as e:
5794f44304bSSimon Glass            self._DoTestFile('25_pack_zero_size.dts')
5804f44304bSSimon Glass        self.assertIn("Node '/binman/u-boot-spl': Position 0x0 (0) overlaps "
5814f44304bSSimon Glass                      "with previous entry '/binman/u-boot' ending at 0x4 (4)",
5824f44304bSSimon Glass                      str(e.exception))
5834f44304bSSimon Glass
5844f44304bSSimon Glass    def testPackUbootDtb(self):
5854f44304bSSimon Glass        """Test that a device tree can be added to U-Boot"""
5864f44304bSSimon Glass        data = self._DoReadFile('26_pack_u_boot_dtb.dts')
5874f44304bSSimon Glass        self.assertEqual(U_BOOT_NODTB_DATA + U_BOOT_DTB_DATA, data)
588*e0ff8551SSimon Glass
589*e0ff8551SSimon Glass    def testPackX86RomNoSize(self):
590*e0ff8551SSimon Glass        """Test that the end-at-4gb property requires a size property"""
591*e0ff8551SSimon Glass        with self.assertRaises(ValueError) as e:
592*e0ff8551SSimon Glass            self._DoTestFile('27_pack_4gb_no_size.dts')
593*e0ff8551SSimon Glass        self.assertIn("Image '/binman': Image size must be provided when "
594*e0ff8551SSimon Glass                      "using end-at-4gb", str(e.exception))
595*e0ff8551SSimon Glass
596*e0ff8551SSimon Glass    def testPackX86RomOutside(self):
597*e0ff8551SSimon Glass        """Test that the end-at-4gb property checks for position boundaries"""
598*e0ff8551SSimon Glass        with self.assertRaises(ValueError) as e:
599*e0ff8551SSimon Glass            self._DoTestFile('28_pack_4gb_outside.dts')
600*e0ff8551SSimon Glass        self.assertIn("Node '/binman/u-boot': Position 0x0 (0) is outside "
601*e0ff8551SSimon Glass                      "the image starting at 0xfffffff0 (4294967280)",
602*e0ff8551SSimon Glass                      str(e.exception))
603*e0ff8551SSimon Glass
604*e0ff8551SSimon Glass    def testPackX86Rom(self):
605*e0ff8551SSimon Glass        """Test that a basic x86 ROM can be created"""
606*e0ff8551SSimon Glass        data = self._DoReadFile('29_x86-rom.dts')
607*e0ff8551SSimon Glass        self.assertEqual(U_BOOT_DATA + chr(0) * 3 + U_BOOT_SPL_DATA +
608*e0ff8551SSimon Glass                         chr(0) * 6, data)
609*e0ff8551SSimon Glass
610*e0ff8551SSimon Glass    def testPackX86RomMeNoDesc(self):
611*e0ff8551SSimon Glass        """Test that an invalid Intel descriptor entry is detected"""
612*e0ff8551SSimon Glass        TestFunctional._MakeInputFile('descriptor.bin', '')
613*e0ff8551SSimon Glass        with self.assertRaises(ValueError) as e:
614*e0ff8551SSimon Glass            self._DoTestFile('31_x86-rom-me.dts')
615*e0ff8551SSimon Glass        self.assertIn("Node '/binman/intel-descriptor': Cannot find FD "
616*e0ff8551SSimon Glass                      "signature", str(e.exception))
617*e0ff8551SSimon Glass
618*e0ff8551SSimon Glass    def testPackX86RomBadDesc(self):
619*e0ff8551SSimon Glass        """Test that the Intel requires a descriptor entry"""
620*e0ff8551SSimon Glass        with self.assertRaises(ValueError) as e:
621*e0ff8551SSimon Glass            self._DoTestFile('30_x86-rom-me-no-desc.dts')
622*e0ff8551SSimon Glass        self.assertIn("Node '/binman/intel-me': No position set with "
623*e0ff8551SSimon Glass                      "pos-unset: should another entry provide this correct "
624*e0ff8551SSimon Glass                      "position?", str(e.exception))
625*e0ff8551SSimon Glass
626*e0ff8551SSimon Glass    def testPackX86RomMe(self):
627*e0ff8551SSimon Glass        """Test that an x86 ROM with an ME region can be created"""
628*e0ff8551SSimon Glass        data = self._DoReadFile('31_x86-rom-me.dts')
629*e0ff8551SSimon Glass        self.assertEqual(ME_DATA, data[0x1000:0x1000 + len(ME_DATA)])
630*e0ff8551SSimon Glass
631*e0ff8551SSimon Glass    def testPackVga(self):
632*e0ff8551SSimon Glass        """Test that an image with a VGA binary can be created"""
633*e0ff8551SSimon Glass        data = self._DoReadFile('32_intel-vga.dts')
634*e0ff8551SSimon Glass        self.assertEqual(VGA_DATA, data[:len(VGA_DATA)])
635*e0ff8551SSimon Glass
636*e0ff8551SSimon Glass    def testPackStart16(self):
637*e0ff8551SSimon Glass        """Test that an image with an x86 start16 region can be created"""
638*e0ff8551SSimon Glass        data = self._DoReadFile('33_x86-start16.dts')
639*e0ff8551SSimon Glass        self.assertEqual(X86_START16_DATA, data[:len(X86_START16_DATA)])
640*e0ff8551SSimon Glass
641*e0ff8551SSimon Glass    def testPackUbootMicrocode(self):
642*e0ff8551SSimon Glass        """Test that x86 microcode can be handled correctly
643*e0ff8551SSimon Glass
644*e0ff8551SSimon Glass        We expect to see the following in the image, in order:
645*e0ff8551SSimon Glass            u-boot-nodtb.bin with a microcode pointer inserted at the correct
646*e0ff8551SSimon Glass                place
647*e0ff8551SSimon Glass            u-boot.dtb with the microcode removed
648*e0ff8551SSimon Glass            the microcode
649*e0ff8551SSimon Glass        """
650*e0ff8551SSimon Glass        data = self._DoReadFile('34_x86_ucode.dts', True)
651*e0ff8551SSimon Glass
652*e0ff8551SSimon Glass        # Now check the device tree has no microcode
653*e0ff8551SSimon Glass        second = data[len(U_BOOT_NODTB_DATA):]
654*e0ff8551SSimon Glass        fname = tools.GetOutputFilename('test.dtb')
655*e0ff8551SSimon Glass        with open(fname, 'wb') as fd:
656*e0ff8551SSimon Glass            fd.write(second)
657*e0ff8551SSimon Glass        fdt = fdt_select.FdtScan(fname)
658*e0ff8551SSimon Glass        ucode = fdt.GetNode('/microcode')
659*e0ff8551SSimon Glass        self.assertTrue(ucode)
660*e0ff8551SSimon Glass        for node in ucode.subnodes:
661*e0ff8551SSimon Glass            self.assertFalse(node.props.get('data'))
662*e0ff8551SSimon Glass
663*e0ff8551SSimon Glass        fdt_len = self.GetFdtLen(second)
664*e0ff8551SSimon Glass        third = second[fdt_len:]
665*e0ff8551SSimon Glass
666*e0ff8551SSimon Glass        # Check that the microcode appears immediately after the Fdt
667*e0ff8551SSimon Glass        # This matches the concatenation of the data properties in
668*e0ff8551SSimon Glass        # the /microcode/update@xxx nodes in x86_ucode.dts.
669*e0ff8551SSimon Glass        ucode_data = struct.pack('>4L', 0x12345678, 0x12345679, 0xabcd0000,
670*e0ff8551SSimon Glass                                 0x78235609)
671*e0ff8551SSimon Glass        self.assertEqual(ucode_data, third[:len(ucode_data)])
672*e0ff8551SSimon Glass        ucode_pos = len(U_BOOT_NODTB_DATA) + fdt_len
673*e0ff8551SSimon Glass
674*e0ff8551SSimon Glass        # Check that the microcode pointer was inserted. It should match the
675*e0ff8551SSimon Glass        # expected position and size
676*e0ff8551SSimon Glass        pos_and_size = struct.pack('<2L', 0xfffffe00 + ucode_pos,
677*e0ff8551SSimon Glass                                   len(ucode_data))
678*e0ff8551SSimon Glass        first = data[:len(U_BOOT_NODTB_DATA)]
679*e0ff8551SSimon Glass        self.assertEqual('nodtb with microcode' + pos_and_size +
680*e0ff8551SSimon Glass                         ' somewhere in here', first)
681*e0ff8551SSimon Glass
682*e0ff8551SSimon Glass    def _RunPackUbootSingleMicrocode(self, collate):
683*e0ff8551SSimon Glass        """Test that x86 microcode can be handled correctly
684*e0ff8551SSimon Glass
685*e0ff8551SSimon Glass        We expect to see the following in the image, in order:
686*e0ff8551SSimon Glass            u-boot-nodtb.bin with a microcode pointer inserted at the correct
687*e0ff8551SSimon Glass                place
688*e0ff8551SSimon Glass            u-boot.dtb with the microcode
689*e0ff8551SSimon Glass            an empty microcode region
690*e0ff8551SSimon Glass        """
691*e0ff8551SSimon Glass        # We need the libfdt library to run this test since only that allows
692*e0ff8551SSimon Glass        # finding the offset of a property. This is required by
693*e0ff8551SSimon Glass        # Entry_u_boot_dtb_with_ucode.ObtainContents().
694*e0ff8551SSimon Glass        if not fdt_select.have_libfdt:
695*e0ff8551SSimon Glass            return
696*e0ff8551SSimon Glass        data = self._DoReadFile('35_x86_single_ucode.dts', True)
697*e0ff8551SSimon Glass
698*e0ff8551SSimon Glass        second = data[len(U_BOOT_NODTB_DATA):]
699*e0ff8551SSimon Glass
700*e0ff8551SSimon Glass        fdt_len = self.GetFdtLen(second)
701*e0ff8551SSimon Glass        third = second[fdt_len:]
702*e0ff8551SSimon Glass        second = second[:fdt_len]
703*e0ff8551SSimon Glass
704*e0ff8551SSimon Glass        if not collate:
705*e0ff8551SSimon Glass            ucode_data = struct.pack('>2L', 0x12345678, 0x12345679)
706*e0ff8551SSimon Glass            self.assertIn(ucode_data, second)
707*e0ff8551SSimon Glass            ucode_pos = second.find(ucode_data) + len(U_BOOT_NODTB_DATA)
708*e0ff8551SSimon Glass
709*e0ff8551SSimon Glass            # Check that the microcode pointer was inserted. It should match the
710*e0ff8551SSimon Glass            # expected position and size
711*e0ff8551SSimon Glass            pos_and_size = struct.pack('<2L', 0xfffffe00 + ucode_pos,
712*e0ff8551SSimon Glass                                    len(ucode_data))
713*e0ff8551SSimon Glass            first = data[:len(U_BOOT_NODTB_DATA)]
714*e0ff8551SSimon Glass            self.assertEqual('nodtb with microcode' + pos_and_size +
715*e0ff8551SSimon Glass                            ' somewhere in here', first)
716