binman: Add add test for SPL with a microcode pointer

Add a test for this feature. It allows SPL to hold a pointer to the
microcode block. This is used for 64-bit U-Boot on x86.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index c381a70..dff7448 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -26,19 +26,20 @@
 import tout
 
 # Contents of test files, corresponding to different entry types
-U_BOOT_DATA         = '1234'
-U_BOOT_IMG_DATA     = 'img'
-U_BOOT_SPL_DATA     = '567'
-BLOB_DATA           = '89'
-ME_DATA             = '0abcd'
-VGA_DATA            = 'vga'
-U_BOOT_DTB_DATA     = 'udtb'
-X86_START16_DATA    = 'start16'
-X86_START16_SPL_DATA = 'start16spl'
-U_BOOT_NODTB_DATA   = 'nodtb with microcode pointer somewhere in here'
-FSP_DATA            = 'fsp'
-CMC_DATA            = 'cmc'
-VBT_DATA            = 'vbt'
+U_BOOT_DATA           = '1234'
+U_BOOT_IMG_DATA       = 'img'
+U_BOOT_SPL_DATA       = '567'
+BLOB_DATA             = '89'
+ME_DATA               = '0abcd'
+VGA_DATA              = 'vga'
+U_BOOT_DTB_DATA       = 'udtb'
+X86_START16_DATA      = 'start16'
+X86_START16_SPL_DATA  = 'start16spl'
+U_BOOT_NODTB_DATA     = 'nodtb with microcode pointer somewhere in here'
+U_BOOT_SPL_NODTB_DATA = 'splnodtb with microcode pointer somewhere in here'
+FSP_DATA              = 'fsp'
+CMC_DATA              = 'cmc'
+VBT_DATA              = 'vbt'
 
 class TestFunctional(unittest.TestCase):
     """Functional tests for binman
@@ -78,6 +79,8 @@
         TestFunctional._MakeInputFile('spl/u-boot-x86-16bit-spl.bin',
                                       X86_START16_SPL_DATA)
         TestFunctional._MakeInputFile('u-boot-nodtb.bin', U_BOOT_NODTB_DATA)
+        TestFunctional._MakeInputFile('spl/u-boot-spl-nodtb.bin',
+                                      U_BOOT_SPL_NODTB_DATA)
         TestFunctional._MakeInputFile('fsp.bin', FSP_DATA)
         TestFunctional._MakeInputFile('cmc.bin', CMC_DATA)
         TestFunctional._MakeInputFile('vbt.bin', VBT_DATA)
@@ -91,10 +94,6 @@
         with open(self.TestFile('descriptor.bin')) as fd:
             TestFunctional._MakeInputFile('descriptor.bin', fd.read())
 
-        # ELF file with a '__bss_size' symbol
-        with open(self.TestFile('bss_data')) as fd:
-            TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read())
-
     @classmethod
     def tearDownClass(self):
         """Remove the temporary input directory and its contents"""
@@ -653,19 +652,11 @@
         data = self._DoReadFile('33_x86-start16.dts')
         self.assertEqual(X86_START16_DATA, data[:len(X86_START16_DATA)])
 
-    def testPackUbootMicrocode(self):
-        """Test that x86 microcode can be handled correctly
-
-        We expect to see the following in the image, in order:
-            u-boot-nodtb.bin with a microcode pointer inserted at the correct
-                place
-            u-boot.dtb with the microcode removed
-            the microcode
-        """
-        data = self._DoReadFile('34_x86_ucode.dts', True)
+    def _RunMicrocodeTest(self, dts_fname, nodtb_data):
+        data = self._DoReadFile(dts_fname, True)
 
         # Now check the device tree has no microcode
-        second = data[len(U_BOOT_NODTB_DATA):]
+        second = data[len(nodtb_data):]
         fname = tools.GetOutputFilename('test.dtb')
         with open(fname, 'wb') as fd:
             fd.write(second)
@@ -684,13 +675,26 @@
         ucode_data = struct.pack('>4L', 0x12345678, 0x12345679, 0xabcd0000,
                                  0x78235609)
         self.assertEqual(ucode_data, third[:len(ucode_data)])
-        ucode_pos = len(U_BOOT_NODTB_DATA) + fdt_len
+        ucode_pos = len(nodtb_data) + fdt_len
 
         # Check that the microcode pointer was inserted. It should match the
         # expected position and size
         pos_and_size = struct.pack('<2L', 0xfffffe00 + ucode_pos,
                                    len(ucode_data))
-        first = data[:len(U_BOOT_NODTB_DATA)]
+        first = data[:len(nodtb_data)]
+        return first, pos_and_size
+
+    def testPackUbootMicrocode(self):
+        """Test that x86 microcode can be handled correctly
+
+        We expect to see the following in the image, in order:
+            u-boot-nodtb.bin with a microcode pointer inserted at the correct
+                place
+            u-boot.dtb with the microcode removed
+            the microcode
+        """
+        first, pos_and_size = self._RunMicrocodeTest('34_x86_ucode.dts',
+                                                     U_BOOT_NODTB_DATA)
         self.assertEqual('nodtb with microcode' + pos_and_size +
                          ' somewhere in here', first)
 
@@ -823,6 +827,9 @@
 
     def testSplBssPad(self):
         """Test that we can pad SPL's BSS with zeros"""
+        # ELF file with a '__bss_size' symbol
+        with open(self.TestFile('bss_data')) as fd:
+            TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read())
         data = self._DoReadFile('47_spl_bss_pad.dts')
         self.assertEqual(U_BOOT_SPL_DATA + (chr(0) * 10) + U_BOOT_DATA, data)
 
@@ -831,6 +838,23 @@
         data = self._DoReadFile('48_x86-start16-spl.dts')
         self.assertEqual(X86_START16_SPL_DATA, data[:len(X86_START16_SPL_DATA)])
 
+    def testPackUbootSplMicrocode(self):
+        """Test that x86 microcode can be handled correctly in SPL
+
+        We expect to see the following in the image, in order:
+            u-boot-spl-nodtb.bin with a microcode pointer inserted at the
+                correct place
+            u-boot.dtb with the microcode removed
+            the microcode
+        """
+        # ELF file with a '_dt_ucode_base_size' symbol
+        with open(self.TestFile('u_boot_ucode_ptr')) as fd:
+            TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read())
+        first, pos_and_size = self._RunMicrocodeTest('49_x86_ucode_spl.dts',
+                                                     U_BOOT_SPL_NODTB_DATA)
+        self.assertEqual('splnodtb with microc' + pos_and_size +
+                         'ter somewhere in here', first)
+
 
 if __name__ == "__main__":
     unittest.main()