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 <s...@chromium.org> --- Changes in v2: None 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 <s...@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 14abfbf774f..1355c4f55d3 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 @@ -876,6 +877,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): @@ -1956,6 +1960,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@VMwo&FeqCWk3Jr%+r+;%-1{H_bktB+NF)6b33x4 z?USzmm^aJ#Y{$DD#{X{4Ib_Ss!0@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@j17wrsB+0|SF}?!$`zF6VB#UbHIP zbp7@7vLCOGW?OR4^M31Ud8#$@&lMHrGHJt8&lZ2&`sT)7<8$91@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@OQ{ioCV zdHrEeGG8$o&OE33Jae7jk(_h=pY{mq^PF+6`Ra3i#d>ZAh64*sw_Dxbd0ww8D>=P* z^W@~OUw-I(Z)(?+JN{~)!PWBLwn@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot