c2ede641aa54f39d3a503781d0d4c15b9d99b5ea
[platform/kernel/u-boot.git] / tools / binman / etype / intel_ifwi.py
1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright (c) 2016 Google, Inc
3 # Written by Simon Glass <sjg@chromium.org>
4 #
5 # Entry-type module for Intel Management Engine binary blob
6 #
7
8 from collections import OrderedDict
9
10 from binman.entry import Entry
11 from binman.etype.blob_ext import Entry_blob_ext
12 from dtoc import fdt_util
13 from patman import tools
14
15 class Entry_intel_ifwi(Entry_blob_ext):
16     """Entry containing an Intel Integrated Firmware Image (IFWI) file
17
18     Properties / Entry arguments:
19         - filename: Filename of file to read into entry. This is either the
20             IFWI file itself, or a file that can be converted into one using a
21             tool
22         - convert-fit: If present this indicates that the ifwitool should be
23             used to convert the provided file into a IFWI.
24
25     This file contains code and data used by the SoC that is required to make
26     it work. It includes U-Boot TPL, microcode, things related to the CSE
27     (Converged Security Engine, the microcontroller that loads all the firmware)
28     and other items beyond the wit of man.
29
30     A typical filename is 'ifwi.bin' for an IFWI file, or 'fitimage.bin' for a
31     file that will be converted to an IFWI.
32
33     The position of this entry is generally set by the intel-descriptor entry.
34
35     The contents of the IFWI are specified by the subnodes of the IFWI node.
36     Each subnode describes an entry which is placed into the IFWFI with a given
37     sub-partition (and optional entry name).
38
39     Properties for subnodes:
40         - ifwi-subpart: sub-parition to put this entry into, e.g. "IBBP"
41         - ifwi-entry: entry name t use, e.g. "IBBL"
42         - ifwi-replace: if present, indicates that the item should be replaced
43           in the IFWI. Otherwise it is added.
44
45     See README.x86 for information about x86 binary blobs.
46     """
47     def __init__(self, section, etype, node):
48         super().__init__(section, etype, node)
49         self._convert_fit = fdt_util.GetBool(self._node, 'convert-fit')
50         self._ifwi_entries = OrderedDict()
51
52     def ReadNode(self):
53         self._ReadSubnodes()
54         super().ReadNode()
55
56     def _BuildIfwi(self):
57         """Build the contents of the IFWI and write it to the 'data' property"""
58         # Create the IFWI file if needed
59         if self._convert_fit:
60             inname = self._pathname
61             outname = tools.GetOutputFilename('ifwi.bin')
62             tools.RunIfwiTool(inname, tools.CMD_CREATE, outname)
63             self._filename = 'ifwi.bin'
64             self._pathname = outname
65         else:
66             # Provide a different code path here to ensure we have test coverage
67             outname = self._pathname
68
69         # Delete OBBP if it is there, then add the required new items.
70         tools.RunIfwiTool(outname, tools.CMD_DELETE, subpart='OBBP')
71
72         for entry in self._ifwi_entries.values():
73             # First get the input data and put it in a file
74             data = entry.GetPaddedData()
75             uniq = self.GetUniqueName()
76             input_fname = tools.GetOutputFilename('input.%s' % uniq)
77             tools.WriteFile(input_fname, data)
78
79             tools.RunIfwiTool(outname,
80                 tools.CMD_REPLACE if entry._ifwi_replace else tools.CMD_ADD,
81                 input_fname, entry._ifwi_subpart, entry._ifwi_entry_name)
82
83         self.ReadBlobContents()
84         return True
85
86     def ObtainContents(self):
87         """Get the contents for the IFWI
88
89         Unfortunately we cannot create anything from scratch here, as Intel has
90         tools which create precursor binaries with lots of data and settings,
91         and these are not incorporated into binman.
92
93         The first step is to get a file in the IFWI format. This is either
94         supplied directly or is extracted from a fitimage using the 'create'
95         subcommand.
96
97         After that we delete the OBBP sub-partition and add each of the files
98         that we want in the IFWI file, one for each sub-entry of the IWFI node.
99         """
100         self._pathname = tools.GetInputFilename(self._filename,
101                                                 self.section.GetAllowMissing())
102         # Allow the file to be missing
103         if not self._pathname:
104             self.SetContents(b'')
105             self.missing = True
106             return True
107         for entry in self._ifwi_entries.values():
108             if not entry.ObtainContents():
109                 return False
110         return self._BuildIfwi()
111
112     def ProcessContents(self):
113         if self.missing:
114             return True
115         orig_data = self.data
116         self._BuildIfwi()
117         same = orig_data == self.data
118         return same
119
120     def _ReadSubnodes(self):
121         """Read the subnodes to find out what should go in this IFWI"""
122         for node in self._node.subnodes:
123             entry = Entry.Create(self.section, node)
124             entry.ReadNode()
125             entry._ifwi_replace = fdt_util.GetBool(node, 'ifwi-replace')
126             entry._ifwi_subpart = fdt_util.GetString(node, 'ifwi-subpart')
127             entry._ifwi_entry_name = fdt_util.GetString(node, 'ifwi-entry')
128             self._ifwi_entries[entry._ifwi_subpart] = entry
129
130     def WriteSymbols(self, section):
131         """Write symbol values into binary files for access at run time"""
132         if not self.missing:
133             for entry in self._ifwi_entries.values():
134                 entry.WriteSymbols(self)