[U-Boot] [PATCH 35/37] binman: Add support for Intel IFWI entries
Simon Glass
sjg at chromium.org
Fri Jun 28 14:09:17 UTC 2019
An Integrated Firmware Image is used to hold various binaries used for
booting with Apollolake and some later devices. Add support for this.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
tools/binman/etype/intel_descriptor.py | 6 +-
tools/binman/etype/intel_ifwi.py | 100 ++++++++++++++++++
tools/binman/ftest.py | 55 ++++++++++
tools/binman/test/111_x86-rom-ifwi.dts | 29 +++++
tools/binman/test/112_x86-rom-ifwi-nodesc.dts | 28 +++++
tools/binman/test/113_x86-rom-ifwi-nodata.dts | 29 +++++
tools/binman/test/fitimage.bin.gz | Bin 0 -> 8418 bytes
tools/binman/test/ifwi.bin.gz | Bin 0 -> 1884 bytes
8 files changed, 245 insertions(+), 2 deletions(-)
create mode 100644 tools/binman/etype/intel_ifwi.py
create mode 100644 tools/binman/test/111_x86-rom-ifwi.dts
create mode 100644 tools/binman/test/112_x86-rom-ifwi-nodesc.dts
create mode 100644 tools/binman/test/113_x86-rom-ifwi-nodata.dts
create mode 100644 tools/binman/test/fitimage.bin.gz
create mode 100644 tools/binman/test/ifwi.bin.gz
diff --git a/tools/binman/etype/intel_descriptor.py b/tools/binman/etype/intel_descriptor.py
index 65ba2391e69..adea578080c 100644
--- a/tools/binman/etype/intel_descriptor.py
+++ b/tools/binman/etype/intel_descriptor.py
@@ -60,10 +60,12 @@ class Entry_intel_descriptor(Entry_blob):
for i in range(MAX_REGIONS):
self._regions.append(Region(self.data, frba, i))
- # Set the offset for ME (Management Engine) only, for now, since the
- # others are not used
+ # Set the offset for ME (Management Engine) and IFWI (Integrated
+ # Firmware Image), for now, since the others are not used.
info = {}
if self.HasSibling('intel-me'):
info['intel-me'] = [self._regions[REGION_ME].base,
self._regions[REGION_ME].size]
+ if self.HasSibling('intel-ifwi'):
+ info['intel-ifwi'] = [self._regions[REGION_BIOS].base, None]
return info
diff --git a/tools/binman/etype/intel_ifwi.py b/tools/binman/etype/intel_ifwi.py
new file mode 100644
index 00000000000..8c79b2dd291
--- /dev/null
+++ b/tools/binman/etype/intel_ifwi.py
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2016 Google, Inc
+# Written by Simon Glass <sjg at chromium.org>
+#
+# Entry-type module for Intel Management Engine binary blob
+#
+
+from collections import OrderedDict
+
+from entry import Entry
+from blob import Entry_blob
+import fdt_util
+import tools
+
+class Entry_intel_ifwi(Entry_blob):
+ """Entry containing an Intel Integrated Firmware Image (IFWI) file
+
+ Properties / Entry arguments:
+ - filename: Filename of file to read into entry. This is either the
+ IFWI file itself, or a file that can be converted into one using a
+ tool
+ - convert-fit: If present this indicates that the ifwitool should be
+ used to convert the provided file into a IFWI.
+
+ This file contains code and data used by the SoC that is required to make
+ it work. It includes U-Boot TPL, microcode, things related to the CSE
+ (Converged Security Engine, the microcontroller that loads all the firmware)
+ and other items beyond the wit of man.
+
+ A typical filename is 'ifwi.bin' for an IFWI file, or 'fitimage.bin' for a
+ file that will be converted to an IFWI.
+
+ The position of this entry is generally set by the intel-descriptor entry.
+
+ The contents of the IFWI are specified by the subnodes of the IFWI node.
+ Each subnode describes an entry which is placed into the IFWFI with a given
+ sub-partition (and optional entry name).
+
+ See README.x86 for information about x86 binary blobs.
+ """
+ def __init__(self, section, etype, node):
+ Entry_blob.__init__(self, section, etype, node)
+ self._convert_fit = fdt_util.GetBool(self._node, 'convert-fit')
+ self._ifwi_entries = OrderedDict()
+ self._ReadSubnodes()
+
+ def ObtainContents(self):
+ """Get the contects for the IFWI
+
+ Unfortunately we cannot create anything from scratch here, as Intel has
+ tools which create precursor binaries with lots of data and settings,
+ and these are not incorporated into binman.
+
+ The first step is to get a file in the IFWI format. This is either
+ supplied directly or is extracted from a fitimage using the 'create'
+ subcommand.
+
+ After that we delete the OBBP sub-partition and add each of the files
+ that we want in the IFWI file, one for each sub-entry of the IWFI node.
+ """
+ self._pathname = tools.GetInputFilename(self._filename)
+
+ # Create the IFWI file if needed
+ if self._convert_fit:
+ inname = self._pathname
+ outname = tools.GetOutputFilename('ifwi.bin')
+ tools.RunIfwiTool(inname, tools.CMD_CREATE, outname)
+ self._filename = 'ifwi.bin'
+ self._pathname = outname
+ else:
+ # Provide a different code path here to ensure we have test coverage
+ inname = self._pathname
+
+ # Delete OBBP if it is there, then add the required new items.
+ tools.RunIfwiTool(inname, tools.CMD_DELETE, subpart='OBBP')
+
+ for entry in self._ifwi_entries.values():
+ # First get the input data and put it in a file
+ if not entry.ObtainContents():
+ return False
+ data = entry.GetData()
+ uniq = self.GetUniqueName()
+ input_fname = tools.GetOutputFilename('input.%s' % uniq)
+ tools.WriteFile(input_fname, data)
+
+ tools.RunIfwiTool(inname,
+ tools.CMD_REPLACE if entry._ifwi_replace else tools.CMD_ADD,
+ input_fname, entry._ifwi_subpart, entry._ifwi_entry_name)
+
+ self.ReadBlobContents()
+ return True
+
+ def _ReadSubnodes(self):
+ """Read the subnodes to find out what should go in this IFWI"""
+ for node in self._node.subnodes:
+ entry = Entry.Create(self.section, node)
+ entry._ifwi_replace = fdt_util.GetBool(node, 'replace')
+ entry._ifwi_subpart = fdt_util.GetString(node, 'ifwi-subpart')
+ entry._ifwi_entry_name = fdt_util.GetString(node, 'ifwi-entry')
+ self._ifwi_entries[entry._ifwi_subpart] = entry
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index ebd62b93fa7..5cb6cd5245b 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -27,6 +27,7 @@ import fdt
import fdt_util
import fmap_util
import test_util
+import gzip
import state
import tools
import tout
@@ -864,6 +865,9 @@ class TestFunctional(unittest.TestCase):
def testPackX86RomMe(self):
"""Test that an x86 ROM with an ME region can be created"""
data = self._DoReadFile('031_x86-rom-me.dts')
+ expected_desc = tools.ReadFile(self.TestFile('descriptor.bin'))
+ if data[:0x1000] != expected_desc:
+ self.fail('Expected descriptor binary at start of image')
self.assertEqual(ME_DATA, data[0x1000:0x1000 + len(ME_DATA)])
def testPackVga(self):
@@ -1941,6 +1945,57 @@ class TestFunctional(unittest.TestCase):
cfile2 = cbfs.files['hello']
self.assertEqual(U_BOOT_DTB_DATA, cfile2.data)
+ def _SetupIfwi(self, fname):
+ """Set up to run an IFWI test
+
+ Args:
+ fname: Filename of input file to provide (fitimage.bin or ifwi.bin)
+ """
+ self._SetupSplElf()
+
+ # Intel Integrated Firmware Image (IFWI) file
+ with gzip.open(self.TestFile('%s.gz' % fname), 'rb') as fd:
+ data = fd.read()
+ TestFunctional._MakeInputFile(fname,data)
+
+ def _CheckIfwi(self, data):
+ """Check that an image with an IFWI contains the correct output
+
+ Args:
+ data: Conents of output file
+ """
+ expected_desc = tools.ReadFile(self.TestFile('descriptor.bin'))
+ if data[:0x1000] != expected_desc:
+ self.fail('Expected descriptor binary at start of image')
+
+ # We expect to find the TPL wil in subpart IBBP entry IBBL
+ image_fname = tools.GetOutputFilename('image.bin')
+ tpl_fname = tools.GetOutputFilename('tpl.out')
+ tools.RunIfwiTool(image_fname, tools.CMD_EXTRACT, fname=tpl_fname,
+ subpart='IBBP', entry_name='IBBL')
+
+ tpl_data = tools.ReadFile(tpl_fname)
+ self.assertEqual(tpl_data[:len(U_BOOT_TPL_DATA)], U_BOOT_TPL_DATA)
+
+ def testPackX86RomIfwi(self):
+ """Test that an x86 ROM with Integrated Firmware Image can be created"""
+ self._SetupIfwi('fitimage.bin')
+ data = self._DoReadFile('111_x86-rom-ifwi.dts')
+ self._CheckIfwi(data)
+
+ def testPackX86RomIfwiNoDesc(self):
+ """Test that an x86 ROM with IFWI can be created from an ifwi.bin file"""
+ self._SetupIfwi('ifwi.bin')
+ data = self._DoReadFile('112_x86-rom-ifwi-nodesc.dts')
+ self._CheckIfwi(data)
+
+ def testPackX86RomIfwiNoData(self):
+ """Test that an x86 ROM with IFWI handles missing data"""
+ self._SetupIfwi('ifwi.bin')
+ with self.assertRaises(ValueError) as e:
+ data = self._DoReadFile('113_x86-rom-ifwi-nodata.dts')
+ self.assertIn('Could not complete processing of contents',
+ str(e.exception))
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/test/111_x86-rom-ifwi.dts b/tools/binman/test/111_x86-rom-ifwi.dts
new file mode 100644
index 00000000000..63b5972cc8e
--- /dev/null
+++ b/tools/binman/test/111_x86-rom-ifwi.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ sort-by-offset;
+ end-at-4gb;
+ size = <0x800000>;
+ intel-descriptor {
+ filename = "descriptor.bin";
+ };
+
+ intel-ifwi {
+ offset-unset;
+ filename = "fitimage.bin";
+ convert-fit;
+
+ u-boot-tpl {
+ replace;
+ ifwi-subpart = "IBBP";
+ ifwi-entry = "IBBL";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/112_x86-rom-ifwi-nodesc.dts b/tools/binman/test/112_x86-rom-ifwi-nodesc.dts
new file mode 100644
index 00000000000..21ec4654ffe
--- /dev/null
+++ b/tools/binman/test/112_x86-rom-ifwi-nodesc.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ sort-by-offset;
+ end-at-4gb;
+ size = <0x800000>;
+ intel-descriptor {
+ filename = "descriptor.bin";
+ };
+
+ intel-ifwi {
+ offset-unset;
+ filename = "ifwi.bin";
+
+ u-boot-tpl {
+ replace;
+ ifwi-subpart = "IBBP";
+ ifwi-entry = "IBBL";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/113_x86-rom-ifwi-nodata.dts b/tools/binman/test/113_x86-rom-ifwi-nodata.dts
new file mode 100644
index 00000000000..62486fd990e
--- /dev/null
+++ b/tools/binman/test/113_x86-rom-ifwi-nodata.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ sort-by-offset;
+ end-at-4gb;
+ size = <0x800000>;
+ intel-descriptor {
+ filename = "descriptor.bin";
+ };
+
+ intel-ifwi {
+ offset-unset;
+ filename = "ifwi.bin";
+
+ _testing {
+ return-unknown-contents;
+ replace;
+ ifwi-subpart = "IBBP";
+ ifwi-entry = "IBBL";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/fitimage.bin.gz b/tools/binman/test/fitimage.bin.gz
new file mode 100644
index 0000000000000000000000000000000000000000..0a9dcfc424845c89436f119eeda8983e12191364
GIT binary patch
literal 8418
zcmb2|=HM`q;)`WqPRlIG%uP&B)l16EV|aVpI$I=Ag6%<mnt9=#BWpO4b~+vLOWC+N
zGEDm5X){K_?udv=$0N5mnzpvuJ8;ilP_{_yCCgv&e=NC2ifq&M3zhD9#`K=wJm+M&
zU)r}bMQPpNTX@)B&#nJbw@>iwic{C_dF=b~^?`Hc!()y2E=_)}AHVn9-x@!`?a$ax
zzr0fzJx_kkYyR8jE{kOgS41Cs at VMwo&FeqCWk3Jr%+r+;%-1{H_bktB+NF)6b33x4
z?USzmm^aJ#Y{$DD#{X{4Ib_Ss!0 at N1-23<Agx?9(x4wTguZTXCquni7ta;GiB<ODE
z)vRjW>+epq8>v6)m>F|_ozktf7elWHSAVcnPA}eC<?nat<*ii`=}-Ttxo1gQUESUO
z_-KLp!k&+;hO><;S6z<LY<_>{YtX#wvvQZDZ at j17wrsB+0|SF}?!$`zF6VB#UbHIP
zbp7 at 7vLCOGW?OR4^M31Ud8#$@&lMHrGHJt8&lZ2&`sT)7<8$91 at 9(yk30u6kb@%qm
z5nI>)HMz>Y{Cr8$<dW-YPwLI*-?}JaxA^bL8~yWo<NyA<v!^aK*dFLJh7aL4dU7p+
z3?OKTH+%bkGaH06N{)sALtRd);UbUqoo=hFH%8^2o?9L2vRV|BY#z)vd;6DtG=xS&
zU^E0qLjWxVZg7p(A!tD|${h`X(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R
z7!85Z5Eu=C(GVC7fzc2c4S~@RASnd?cT7Fnq181bW63Vz)mOj$$Z=mg?_|5t*296j
zwUWZu&Rcyob?v?2)yx0xlsx%5z9#i=dhzn9QMaQQ85nX{xsU%=FZ!k3b?x!yy>a$i
lx9Z%On{wd&ldm8bY};eMGaRUj;m<t(^-=eBGaRU9006rUF!lfd
literal 0
HcmV?d00001
diff --git a/tools/binman/test/ifwi.bin.gz b/tools/binman/test/ifwi.bin.gz
new file mode 100644
index 0000000000000000000000000000000000000000..25d72892944d7de2813cede71ec96f581cece949
GIT binary patch
literal 1884
zcmb2|=HQs3%ooeRoS9ahsh5<Q$ME*HwfErw5rzlCua);be)Q%-<dPjbMM?!jc5(FW
zT3zyioug^9y<<4L`N5-S|1bS+cI~)|leg%8{W;&hn3$WZo-EM&@=hViuIokil0BmS
zPfKcMoYYSi46T}d;-{<R#-OW<cWLG+J+pgj|6eoSD{$$?)LWG{;-4I^-P at OQ{ioCV
zdHrEeGG8$o&OE33Jae7jk(_h=pY{mq^PF+6`Ra3i#d>ZAh64*sw_Dxbd0ww8D>=P*
z^W@~OUw-I(Z)(?+JN{~)!PWBLwn at 7MOY`Hd->*LY?P+wqeChi7+oxY`ZC%|RqCGwQ
zUGTj-xATuq*m6Jp$^K}cjdFXdw_ILdTb}>t%TLSq^LW0RGXTN<Lk82Hf*3$hmviO+
zW;O_WlpGBKhJEGb0)b1`uAlfR%w}rv&%>pXfuSFnfC2L-b8%e#XaJ3dz-S1J%n+#C
OAO70lJukxo2?hX1K&cV{
literal 0
HcmV?d00001
--
2.22.0.410.gd8fdbe21b5-goog
More information about the U-Boot
mailing list