Skip to content

Commit

Permalink
binman: Add support for Intel FIT
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
sjg20 committed Oct 15, 2019
1 parent 5e23918 commit 5af1207
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 0 deletions.
19 changes: 19 additions & 0 deletions tools/binman/README.entries
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------------------------------------------------------------------------

Expand Down
32 changes: 32 additions & 0 deletions tools/binman/etype/intel_fit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2016 Google, Inc
# Written by Simon Glass <[email protected]>
#
# 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
41 changes: 41 additions & 0 deletions tools/binman/etype/intel_fit_ptr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2016 Google, Inc
# Written by Simon Glass <[email protected]>
#
# 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)
20 changes: 20 additions & 0 deletions tools/binman/ftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3264,6 +3264,26 @@ def testPackReset16Tpl(self):
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()
20 changes: 20 additions & 0 deletions tools/binman/test/147_intel_fit.dts
Original file line number Diff line number Diff line change
@@ -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 {
};
};
};
17 changes: 17 additions & 0 deletions tools/binman/test/148_intel_fit_missing.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/dts-v1/;

/ {
#address-cells = <1>;
#size-cells = <1>;

binman {
end-at-4gb;
size = <0x80>;

u-boot {
};

intel-fit-ptr {
};
};
};

0 comments on commit 5af1207

Please sign in to comment.