binman: Add a bintool implementation for ifwitool
[platform/kernel/u-boot.git] / tools / binman / btool / ifwitool.py
1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright 2022 Google LLC
3 #
4 """Bintool implementation for ifwitool
5
6 ifwitool provides a way to package firmware in an Intel Firmware Image (IFWI)
7 file on some Intel SoCs, e.g. Apolo Lake.
8
9 Documentation is not really available so far as I can tell
10
11 Source code is at tools/ifwitool.c which is a cleaned-up version of
12 https://github.com/coreboot/coreboot/blob/master/util/cbfstool/ifwitool.c
13
14 Here is the help:
15
16 ifwitool: Utility for IFWI manipulation
17
18 USAGE:
19  /tmp/b/sandbox/tools/ifwitool [-h]
20  /tmp/b/sandbox/tools/ifwitool FILE COMMAND [PARAMETERS]
21
22 COMMANDs:
23  add -f FILE -n NAME [-d -e ENTRY]
24  create -f FILE
25  delete -n NAME
26  extract -f FILE -n NAME [-d -e ENTRY]
27  print [-d]
28  replace -f FILE -n NAME [-d -e ENTRY]
29 OPTIONs:
30  -f FILE : File to read/write/create/extract
31  -d      : Perform directory operation
32  -e ENTRY: Name of directory entry to operate on
33  -v      : Verbose level
34  -h      : Help message
35  -n NAME : Name of sub-partition to operate on
36
37 NAME should be one of:
38 SMIP(SMIP)
39 RBEP(CSE_RBE)
40 FTPR(CSE_BUP)
41 UCOD(Microcode)
42 IBBP(Bootblock)
43 S_BPDT(S-BPDT)
44 OBBP(OEM boot block)
45 NFTP(CSE_MAIN)
46 ISHP(ISH)
47 DLMP(CSE_IDLM)
48 IFP_OVERRIDE(IFP_OVERRIDE)
49 DEBUG_TOKENS(Debug Tokens)
50 UFS_PHY(UFS Phy)
51 UFS_GPP(UFS GPP)
52 PMCP(PMC firmware)
53 IUNP(IUNIT)
54 NVM_CONFIG(NVM Config)
55 UEP(UEP)
56 UFS_RATE_B(UFS Rate B Config)
57 """
58
59 from binman import bintool
60
61 class Bintoolifwitool(bintool.Bintool):
62     """Handles the 'ifwitool' tool
63
64     This bintool supports running `ifwitool` with some basic parameters as
65     neeed by binman. It includes creating a file from a FIT as well as adding,
66     replacing, deleting and extracting subparts.
67
68     The tool is built as part of U-Boot, but a binary version can be fetched if
69     required.
70
71     ifwitool provides a way to package firmware in an Intel Firmware Image
72     (IFWI) file on some Intel SoCs, e.g. Apolo Lake.
73     """
74     def __init__(self, name):
75         super().__init__(name, 'Manipulate Intel IFWI files')
76
77     def create_ifwi(self, intel_fit, ifwi_file):
78         """Create a new IFWI file, using an existing Intel FIT binary
79
80         Args:
81             intel_fit (str): Filename of exist Intel FIT file
82             ifwi_file (str): Output filename to write the new IFWI too
83
84         Returns:
85             str: Tool output
86         """
87         args = [intel_fit, 'create', '-f', ifwi_file]
88         return self.run_cmd(*args)
89
90     def delete_subpart(self, ifwi_file, subpart):
91         """Delete a subpart within the IFWI file
92
93         Args:
94             ifwi_file (str): IFWI filename to update
95             subpart (str): Name of subpart to delete, e.g. 'OBBP'
96
97         Returns:
98             str: Tool output
99         """
100         args = [ifwi_file, 'delete', '-n', subpart]
101         return self.run_cmd(*args)
102
103     # pylint: disable=R0913
104     def add_subpart(self, ifwi_file, subpart, entry_name, infile,
105                     replace=False):
106         """Add or replace a subpart within the IFWI file
107
108         Args:
109             ifwi_file (str): IFWI filename to update
110             subpart (str): Name of subpart to add/replace
111             entry_nme (str): Name of entry to add/replace
112             replace (bool): True to replace the existing entry, False to add a
113                 new one
114
115         Returns:
116             str: Tool output
117         """
118         args = [
119             ifwi_file,
120             'replace' if replace else 'add',
121             '-n', subpart,
122             '-d', '-e', entry_name,
123             '-f', infile,
124             ]
125         return self.run_cmd(*args)
126
127     def extract(self, ifwi_file, subpart, entry_name, outfile):
128         """Extract a subpart from the IFWI file
129
130         Args:
131             ifwi_file (str): IFWI filename to extract from
132             subpart (str): Name of subpart to extract
133             entry_nme (str): Name of entry to extract
134
135         Returns:
136             str: Tool output
137         """
138         args = [
139             ifwi_file,
140             'extract',
141             '-n', subpart,
142             '-d', '-e', entry_name,
143             '-f', outfile,
144             ]
145         return self.run_cmd(*args)
146
147     def fetch(self, method):
148         """Fetch handler for ifwitool
149
150         This installs ifwitool using a binary download.
151
152         Args:
153             method (FETCH_...): Method to use
154
155         Returns:
156             True if the file was fetched, None if a method other than FETCH_BIN
157             was requested
158
159         Raises:
160             Valuerror: Fetching could not be completed
161         """
162         if method != bintool.FETCH_BIN:
163             return None
164         fname, tmpdir = self.fetch_from_drive(
165             '18JDghOxlt2Hcc5jv51O1t6uNVHQ0XKJS')
166         return fname, tmpdir