mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
binman: Add support for Intel IFWI entries
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@chromium.org>
This commit is contained in:
parent
ac62fba459
commit
c5ac138828
8 changed files with 245 additions and 2 deletions
|
@ -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
|
||||
|
|
100
tools/binman/etype/intel_ifwi.py
Normal file
100
tools/binman/etype/intel_ifwi.py
Normal file
|
@ -0,0 +1,100 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright (c) 2016 Google, Inc
|
||||
# Written by Simon Glass <sjg@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
|
|
@ -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()
|
||||
|
|
29
tools/binman/test/111_x86-rom-ifwi.dts
Normal file
29
tools/binman/test/111_x86-rom-ifwi.dts
Normal file
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
28
tools/binman/test/112_x86-rom-ifwi-nodesc.dts
Normal file
28
tools/binman/test/112_x86-rom-ifwi-nodesc.dts
Normal file
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
29
tools/binman/test/113_x86-rom-ifwi-nodata.dts
Normal file
29
tools/binman/test/113_x86-rom-ifwi-nodata.dts
Normal file
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
BIN
tools/binman/test/fitimage.bin.gz
Normal file
BIN
tools/binman/test/fitimage.bin.gz
Normal file
Binary file not shown.
BIN
tools/binman/test/ifwi.bin.gz
Normal file
BIN
tools/binman/test/ifwi.bin.gz
Normal file
Binary file not shown.
Loading…
Reference in a new issue