1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright © 2022 Intel Corporation
4  */
5 
6 #ifndef _XE_UC_FW_ABI_H
7 #define _XE_UC_FW_ABI_H
8 
9 #include <linux/build_bug.h>
10 #include <linux/types.h>
11 
12 /**
13  * DOC: CSS-based Firmware Layout
14  *
15  * The CSS-based firmware structure is used for GuC releases on all platforms
16  * and for HuC releases up to DG1. Starting from DG2/MTL the HuC uses the GSC
17  * layout instead.
18  * The CSS firmware layout looks like this::
19  *
20  *      +======================================================================+
21  *      |  Firmware blob                                                       |
22  *      +===============+===============+============+============+============+
23  *      |  CSS header   |     uCode     |  RSA key   |  modulus   |  exponent  |
24  *      +===============+===============+============+============+============+
25  *       <-header size->                 <---header size continued ----------->
26  *       <--- size ----------------------------------------------------------->
27  *                                       <-key size->
28  *                                                    <-mod size->
29  *                                                                 <-exp size->
30  *
31  * The firmware may or may not have modulus key and exponent data. The header,
32  * uCode and RSA signature are must-have components that will be used by driver.
33  * Length of each components, which is all in dwords, can be found in header.
34  * In the case that modulus and exponent are not present in fw, a.k.a truncated
35  * image, the length value still appears in header.
36  *
37  * Driver will do some basic fw size validation based on the following rules:
38  *
39  * 1. Header, uCode and RSA are must-have components.
40  * 2. All firmware components, if they present, are in the sequence illustrated
41  *    in the layout table above.
42  * 3. Length info of each component can be found in header, in dwords.
43  * 4. Modulus and exponent key are not required by driver. They may not appear
44  *    in fw. So driver will load a truncated firmware in this case.
45  */
46 
47 struct uc_css_header {
48 	u32 module_type;
49 	/*
50 	 * header_size includes all non-uCode bits, including css_header, rsa
51 	 * key, modulus key and exponent data.
52 	 */
53 	u32 header_size_dw;
54 	u32 header_version;
55 	u32 module_id;
56 	u32 module_vendor;
57 	u32 date;
58 #define CSS_DATE_DAY			(0xFF << 0)
59 #define CSS_DATE_MONTH			(0xFF << 8)
60 #define CSS_DATE_YEAR			(0xFFFF << 16)
61 	u32 size_dw; /* uCode plus header_size_dw */
62 	u32 key_size_dw;
63 	u32 modulus_size_dw;
64 	u32 exponent_size_dw;
65 	u32 time;
66 #define CSS_TIME_HOUR			(0xFF << 0)
67 #define CSS_DATE_MIN			(0xFF << 8)
68 #define CSS_DATE_SEC			(0xFFFF << 16)
69 	char username[8];
70 	char buildnumber[12];
71 	u32 sw_version;
72 #define CSS_SW_VERSION_UC_MAJOR		(0xFF << 16)
73 #define CSS_SW_VERSION_UC_MINOR		(0xFF << 8)
74 #define CSS_SW_VERSION_UC_PATCH		(0xFF << 0)
75 	union {
76 		u32 submission_version; /* only applies to GuC */
77 		u32 reserved2;
78 	};
79 	u32 reserved0[12];
80 	union {
81 		u32 private_data_size; /* only applies to GuC */
82 		u32 reserved1;
83 	};
84 	u32 header_info;
85 } __packed;
86 static_assert(sizeof(struct uc_css_header) == 128);
87 
88 /**
89  * DOC: GSC-based Firmware Layout
90  *
91  * The GSC-based firmware structure is used for GSC releases on all platforms
92  * and for HuC releases starting from DG2/MTL. Older HuC releases use the
93  * CSS-based layout instead. Differently from the CSS headers, the GSC headers
94  * uses a directory + entries structure (i.e., there is array of addresses
95  * pointing to specific header extensions identified by a name). Although the
96  * header structures are the same, some of the entries are specific to GSC while
97  * others are specific to HuC. The manifest header entry, which includes basic
98  * information about the binary (like the version) is always present, but it is
99  * named differently based on the binary type.
100  *
101  * The HuC binary starts with a Code Partition Directory (CPD) header. The
102  * entries we're interested in for use in the driver are:
103  *
104  * 1. "HUCP.man": points to the manifest header for the HuC.
105  * 2. "huc_fw": points to the FW code. On platforms that support load via DMA
106  *    and 2-step HuC authentication (i.e. MTL+) this is a full CSS-based binary,
107  *    while if the GSC is the one doing the load (which only happens on DG2)
108  *    this section only contains the uCode.
109  *
110  * The GSC-based HuC firmware layout looks like this::
111  *
112  *	+================================================+
113  *	|  CPD Header                                    |
114  *	+================================================+
115  *	|  CPD entries[]                                 |
116  *	|      entry1                                    |
117  *	|      ...                                       |
118  *	|      entryX                                    |
119  *	|          "HUCP.man"                            |
120  *	|           ...                                  |
121  *	|           offset  >----------------------------|------o
122  *	|      ...                                       |      |
123  *	|      entryY                                    |      |
124  *	|          "huc_fw"                              |      |
125  *	|           ...                                  |      |
126  *	|           offset  >----------------------------|----------o
127  *	+================================================+      |   |
128  *	                                                        |   |
129  *	+================================================+      |   |
130  *	|  Manifest Header                               |<-----o   |
131  *	|      ...                                       |          |
132  *	|      FW version                                |          |
133  *	|      ...                                       |          |
134  *	+================================================+          |
135  *	                                                            |
136  *	+================================================+          |
137  *	|  FW binary                                     |<---------o
138  *	|      CSS (MTL+ only)                           |
139  *	|      uCode                                     |
140  *	|      RSA Key (MTL+ only)                       |
141  *	|      ...                                       |
142  *	+================================================+
143  *
144  * The GSC binary starts instead with a layout header, which contains the
145  * locations of the various partitions of the binary. The one we're interested
146  * in is the boot1 partition, where we can find a BPDT header followed by
147  * entries, one of which points to the RBE sub-section of the partition, which
148  * contains the CPD. The GSC blob does not contain a CSS-based binary, so we
149  * only need to look for the manifest, which is under the "RBEP.man" CPD entry.
150  * Note that we have no need to find where the actual FW code is inside the
151  * image because the GSC ROM will itself parse the headers to find it and load
152  * it.
153  * The GSC firmware header layout looks like this::
154  *
155  *	+================================================+
156  *	|  Layout Pointers                               |
157  *	|      ...                                       |
158  *	|      Boot1 offset  >---------------------------|------o
159  *	|      ...                                       |      |
160  *	+================================================+      |
161  *	                                                        |
162  *	+================================================+      |
163  *	|  BPDT header                                   |<-----o
164  *	+================================================+
165  *	|  BPDT entries[]                                |
166  *	|      entry1                                    |
167  *	|      ...                                       |
168  *	|      entryX                                    |
169  *	|          type == GSC_RBE                       |
170  *	|          offset  >-----------------------------|------o
171  *	|      ...                                       |      |
172  *	+================================================+      |
173  *	                                                        |
174  *	+================================================+      |
175  *	|  CPD Header                                    |<-----o
176  *	+================================================+
177  *	|  CPD entries[]                                 |
178  *	|      entry1                                    |
179  *	|      ...                                       |
180  *	|      entryX                                    |
181  *	|          "RBEP.man"                            |
182  *	|           ...                                  |
183  *	|           offset  >----------------------------|------o
184  *	|      ...                                       |      |
185  *	+================================================+      |
186  *	                                                        |
187  *	+================================================+      |
188  *	| Manifest Header                                |<-----o
189  *	|  ...                                           |
190  *	|  FW version                                    |
191  *	|  ...                                           |
192  *	|  Security version                              |
193  *	|  ...                                           |
194  *	+================================================+
195  */
196 
197 struct gsc_version {
198 	u16 major;
199 	u16 minor;
200 	u16 hotfix;
201 	u16 build;
202 } __packed;
203 
204 struct gsc_partition {
205 	u32 offset;
206 	u32 size;
207 } __packed;
208 
209 struct gsc_layout_pointers {
210 	u8 rom_bypass_vector[16];
211 
212 	/* size of this header section, not including ROM bypass vector */
213 	u16 size;
214 
215 	/*
216 	 * bit0: Backup copy of layout pointers exists
217 	 * bits1-15: reserved
218 	 */
219 	u8 flags;
220 
221 	u8 reserved;
222 
223 	u32 crc32;
224 
225 	struct gsc_partition datap;
226 	struct gsc_partition boot1;
227 	struct gsc_partition boot2;
228 	struct gsc_partition boot3;
229 	struct gsc_partition boot4;
230 	struct gsc_partition boot5;
231 	struct gsc_partition temp_pages;
232 } __packed;
233 
234 /* Boot partition structures */
235 struct gsc_bpdt_header {
236 	u32 signature;
237 #define GSC_BPDT_HEADER_SIGNATURE 0x000055AA
238 
239 	u16 descriptor_count; /* num of entries after the header */
240 
241 	u8 version;
242 	u8 configuration;
243 
244 	u32 crc32;
245 
246 	u32 build_version;
247 	struct gsc_version tool_version;
248 } __packed;
249 
250 struct gsc_bpdt_entry {
251 	/*
252 	 * Bits 0-15: BPDT entry type
253 	 * Bits 16-17: reserved
254 	 * Bit 18: code sub-partition
255 	 * Bits 19-31: reserved
256 	 */
257 	u32 type;
258 #define GSC_BPDT_ENTRY_TYPE_MASK GENMASK(15, 0)
259 #define GSC_BPDT_ENTRY_TYPE_GSC_RBE 0x1
260 
261 	u32 sub_partition_offset; /* from the base of the BPDT header */
262 	u32 sub_partition_size;
263 } __packed;
264 
265 /* Code partition directory (CPD) structures */
266 struct gsc_cpd_header_v2 {
267 	u32 header_marker;
268 #define GSC_CPD_HEADER_MARKER 0x44504324
269 
270 	u32 num_of_entries;
271 	u8 header_version;
272 	u8 entry_version;
273 	u8 header_length; /* in bytes */
274 	u8 flags;
275 	u32 partition_name;
276 	u32 crc32;
277 } __packed;
278 
279 struct gsc_cpd_entry {
280 	u8 name[12];
281 
282 	/*
283 	 * Bits 0-24: offset from the beginning of the code partition
284 	 * Bit 25: huffman compressed
285 	 * Bits 26-31: reserved
286 	 */
287 	u32 offset;
288 #define GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0)
289 #define GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25)
290 
291 	/*
292 	 * Module/Item length, in bytes. For Huffman-compressed modules, this
293 	 * refers to the uncompressed size. For software-compressed modules,
294 	 * this refers to the compressed size.
295 	 */
296 	u32 length;
297 
298 	u8 reserved[4];
299 } __packed;
300 
301 struct gsc_manifest_header {
302 	u32 header_type; /* 0x4 for manifest type */
303 	u32 header_length; /* in dwords */
304 	u32 header_version;
305 	u32 flags;
306 	u32 vendor;
307 	u32 date;
308 	u32 size; /* In dwords, size of entire manifest (header + extensions) */
309 	u32 header_id;
310 	u32 internal_data;
311 	struct gsc_version fw_version;
312 	u32 security_version;
313 	struct gsc_version meu_kit_version;
314 	u32 meu_manifest_version;
315 	u8 general_data[4];
316 	u8 reserved3[56];
317 	u32 modulus_size; /* in dwords */
318 	u32 exponent_size; /* in dwords */
319 } __packed;
320 
321 #endif
322