binman: Add support for Intel FIT
authorSimon Glass <sjg@chromium.org>
Sat, 24 Aug 2019 13:22:50 +0000 (07:22 -0600)
committerSimon Glass <sjg@chromium.org>
Tue, 15 Oct 2019 14:40:02 +0000 (08:40 -0600)
A Firmware Image Table (FIT) is a data structure defined by Intel which
contains information about various things needed by the SoC, such as
microcode.

Add support for this entry as well as the pointer to it. The contents of
FIT are fixed at present. Future work is needed to support adding
microcode, etc.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/binman/README.entries
tools/binman/etype/intel_fit.py [new file with mode: 0644]
tools/binman/etype/intel_fit_ptr.py [new file with mode: 0644]
tools/binman/ftest.py
tools/binman/test/147_intel_fit.dts [new file with mode: 0644]
tools/binman/test/148_intel_fit_missing.dts [new file with mode: 0644]

index d17b3cb078fc6c7b1c827449dd42257bef386c01..dba51e6daac8397878d70696706048d3fe76ff17 100644 (file)
@@ -391,6 +391,25 @@ See README.x86 for information about x86 binary blobs.
 
 
 
+Entry: intel-fit: Intel Firmware Image Table (FIT)
+--------------------------------------------------
+
+This entry contains a dummy FIT as required by recent Intel CPUs. The FIT
+contains information about the firmware and microcode available in the
+image.
+
+At present binman only supports a basic FIT with no microcode.
+
+
+
+Entry: intel-fit-ptr: Intel Firmware Image Table (FIT) pointer
+--------------------------------------------------------------
+
+This entry contains a pointer to the FIT. It is required to be at address
+0xffffffc0 in the image.
+
+
+
 Entry: intel-fsp: Entry containing an Intel Firmware Support Package (FSP) file
 -------------------------------------------------------------------------------
 
diff --git a/tools/binman/etype/intel_fit.py b/tools/binman/etype/intel_fit.py
new file mode 100644 (file)
index 0000000..23606d2
--- /dev/null
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# Entry-type module for Intel Firmware Image Table
+#
+
+import struct
+
+from blob import Entry_blob
+
+class Entry_intel_fit(Entry_blob):
+    """Intel Firmware Image Table (FIT)
+
+    This entry contains a dummy FIT as required by recent Intel CPUs. The FIT
+    contains information about the firmware and microcode available in the
+    image.
+
+    At present binman only supports a basic FIT with no microcode.
+    """
+    def __init__(self, section, etype, node):
+        Entry_blob.__init__(self, section, etype, node)
+
+    def ReadNode(self):
+        """Force 16-byte alignment as required by FIT pointer"""
+        Entry_blob.ReadNode(self)
+        self.align = 16
+
+    def ObtainContents(self):
+        data = struct.pack('<8sIHBB', '_FIT_   ', 1, 0x100, 0x80, 0x7d)
+        self.SetContents(data)
+        return True
diff --git a/tools/binman/etype/intel_fit_ptr.py b/tools/binman/etype/intel_fit_ptr.py
new file mode 100644 (file)
index 0000000..148b206
--- /dev/null
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# Entry-type module for a pointer to an Intel Firmware Image Table
+#
+
+import struct
+
+from blob import Entry_blob
+
+class Entry_intel_fit_ptr(Entry_blob):
+    """Intel Firmware Image Table (FIT) pointer
+
+    This entry contains a pointer to the FIT. It is required to be at address
+    0xffffffc0 in the image.
+    """
+    def __init__(self, section, etype, node):
+        Entry_blob.__init__(self, section, etype, node)
+        if self.HasSibling('intel-fit') is False:
+            self.Raise("'intel-fit-ptr' section must have an 'intel-fit' sibling")
+
+    def _GetContents(self):
+        fit_pos = self.GetSiblingImagePos('intel-fit')
+        return struct.pack('<II', fit_pos or 0, 0)
+
+    def ObtainContents(self):
+        self.SetContents(self._GetContents())
+        return True
+
+    def ProcessContents(self):
+        """Write an updated version of the FIT pointer to this entry
+
+        This is necessary since image_pos is not available when ObtainContents()
+        is called, since by then the entries have not been packed in the image.
+        """
+        return self.ProcessContentsUpdate(self._GetContents())
+
+    def Pack(self, offset):
+        """Special pack method to set the offset to the right place"""
+        return Entry_blob.Pack(self, 0xffffffc0)
index 04127faa6ffe087bbd710657dda2c1d22c0b58b6..080599fee32a0b51f60f57a6ed7b8d1510213532 100644 (file)
@@ -3264,6 +3264,26 @@ class TestFunctional(unittest.TestCase):
         data = self._DoReadFile('146_x86_reset16_tpl.dts')
         self.assertEqual(X86_RESET16_TPL_DATA, data[:len(X86_RESET16_TPL_DATA)])
 
+    def testPackIntelFit(self):
+        """Test that an image with an Intel FIT and pointer can be created"""
+        data = self._DoReadFile('147_intel_fit.dts')
+        self.assertEqual(U_BOOT_DATA, data[:len(U_BOOT_DATA)])
+        fit = data[16:32];
+        self.assertEqual(b'_FIT_   \x01\x00\x00\x00\x00\x01\x80}' , fit)
+        ptr = struct.unpack('<i', data[0x40:0x44])[0]
+
+        image = control.images['image']
+        entries = image.GetEntries()
+        expected_ptr = entries['intel-fit'].image_pos - (1 << 32)
+        self.assertEqual(expected_ptr, ptr)
+
+    def testPackIntelFitMissing(self):
+        """Test detection of a FIT pointer with not FIT region"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFile('148_intel_fit_missing.dts')
+        self.assertIn("'intel-fit-ptr' section must have an 'intel-fit' sibling",
+                      str(e.exception))
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/147_intel_fit.dts b/tools/binman/test/147_intel_fit.dts
new file mode 100644 (file)
index 0000000..01ec40e
--- /dev/null
@@ -0,0 +1,20 @@
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               end-at-4gb;
+               size = <0x80>;
+
+               u-boot {
+               };
+
+               intel-fit {
+               };
+
+               intel-fit-ptr {
+               };
+       };
+};
diff --git a/tools/binman/test/148_intel_fit_missing.dts b/tools/binman/test/148_intel_fit_missing.dts
new file mode 100644 (file)
index 0000000..388c76b
--- /dev/null
@@ -0,0 +1,17 @@
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               end-at-4gb;
+               size = <0x80>;
+
+               u-boot {
+               };
+
+               intel-fit-ptr {
+               };
+       };
+};