xref: /linux/drivers/gpu/drm/xe/xe_uc_fw_abi.h (revision 55a42f78ffd386e01a5404419f8c5ded7db70a21)
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_rsa_info {
48 	u32 key_size_dw;
49 	u32 modulus_size_dw;
50 	u32 exponent_size_dw;
51 } __packed;
52 
53 struct uc_css_guc_info {
54 	u32 time;
55 #define CSS_TIME_HOUR				(0xFF << 0)
56 #define CSS_TIME_MIN				(0xFF << 8)
57 #define CSS_TIME_SEC				(0xFFFF << 16)
58 	u32 reserved0[5];
59 	u32 sw_version;
60 #define CSS_SW_VERSION_UC_MAJOR			(0xFF << 16)
61 #define CSS_SW_VERSION_UC_MINOR			(0xFF << 8)
62 #define CSS_SW_VERSION_UC_PATCH			(0xFF << 0)
63 	u32 submission_version;
64 	u32 reserved1[11];
65 	u32 header_info;
66 #define CSS_HEADER_INFO_SVN			(0xFF)
67 #define CSS_HEADER_INFO_COPY_VALID		(0x1 << 31)
68 	u32 private_data_size;
69 	u32 ukernel_info;
70 #define CSS_UKERNEL_INFO_DEVICEID		(0xFFFF << 16)
71 #define CSS_UKERNEL_INFO_PRODKEY		(0xFF << 8)
72 #define CSS_UKERNEL_INFO_BUILDTYPE		(0x3 << 2)
73 #define CSS_UKERNEL_INFO_BUILDTYPE_PROD		0
74 #define CSS_UKERNEL_INFO_BUILDTYPE_PREPROD	1
75 #define CSS_UKERNEL_INFO_BUILDTYPE_DEBUG	2
76 #define CSS_UKERNEL_INFO_ENCSTATUS		(0x1 << 1)
77 #define CSS_UKERNEL_INFO_COPY_VALID		(0x1 << 0)
78 } __packed;
79 
80 struct uc_css_header {
81 	u32 module_type;
82 	/*
83 	 * header_size includes all non-uCode bits, including css_header, rsa
84 	 * key, modulus key and exponent data.
85 	 */
86 	u32 header_size_dw;
87 	u32 header_version;
88 	u32 reserved0;
89 	u32 module_vendor;
90 	u32 date;
91 #define CSS_DATE_DAY				(0xFF << 0)
92 #define CSS_DATE_MONTH				(0xFF << 8)
93 #define CSS_DATE_YEAR				(0xFFFF << 16)
94 	u32 size_dw; /* uCode plus header_size_dw */
95 	union {
96 		u32 reserved1[3];
97 		struct uc_css_rsa_info rsa_info;
98 	};
99 	union {
100 		u32 reserved2[22];
101 		struct uc_css_guc_info guc_info;
102 	};
103 } __packed;
104 static_assert(sizeof(struct uc_css_header) == 128);
105 
106 /**
107  * DOC: GSC-based Firmware Layout
108  *
109  * The GSC-based firmware structure is used for GSC releases on all platforms
110  * and for HuC releases starting from DG2/MTL. Older HuC releases use the
111  * CSS-based layout instead. Differently from the CSS headers, the GSC headers
112  * uses a directory + entries structure (i.e., there is array of addresses
113  * pointing to specific header extensions identified by a name). Although the
114  * header structures are the same, some of the entries are specific to GSC while
115  * others are specific to HuC. The manifest header entry, which includes basic
116  * information about the binary (like the version) is always present, but it is
117  * named differently based on the binary type.
118  *
119  * The HuC binary starts with a Code Partition Directory (CPD) header. The
120  * entries we're interested in for use in the driver are:
121  *
122  * 1. "HUCP.man": points to the manifest header for the HuC.
123  * 2. "huc_fw": points to the FW code. On platforms that support load via DMA
124  *    and 2-step HuC authentication (i.e. MTL+) this is a full CSS-based binary,
125  *    while if the GSC is the one doing the load (which only happens on DG2)
126  *    this section only contains the uCode.
127  *
128  * The GSC-based HuC firmware layout looks like this::
129  *
130  *	+================================================+
131  *	|  CPD Header                                    |
132  *	+================================================+
133  *	|  CPD entries[]                                 |
134  *	|      entry1                                    |
135  *	|      ...                                       |
136  *	|      entryX                                    |
137  *	|          "HUCP.man"                            |
138  *	|           ...                                  |
139  *	|           offset  >----------------------------|------o
140  *	|      ...                                       |      |
141  *	|      entryY                                    |      |
142  *	|          "huc_fw"                              |      |
143  *	|           ...                                  |      |
144  *	|           offset  >----------------------------|----------o
145  *	+================================================+      |   |
146  *	                                                        |   |
147  *	+================================================+      |   |
148  *	|  Manifest Header                               |<-----o   |
149  *	|      ...                                       |          |
150  *	|      FW version                                |          |
151  *	|      ...                                       |          |
152  *	+================================================+          |
153  *	                                                            |
154  *	+================================================+          |
155  *	|  FW binary                                     |<---------o
156  *	|      CSS (MTL+ only)                           |
157  *	|      uCode                                     |
158  *	|      RSA Key (MTL+ only)                       |
159  *	|      ...                                       |
160  *	+================================================+
161  *
162  * The GSC binary starts instead with a layout header, which contains the
163  * locations of the various partitions of the binary. The one we're interested
164  * in is the boot1 partition, where we can find a BPDT header followed by
165  * entries, one of which points to the RBE sub-section of the partition, which
166  * contains the CPD. The GSC blob does not contain a CSS-based binary, so we
167  * only need to look for the manifest, which is under the "RBEP.man" CPD entry.
168  * Note that we have no need to find where the actual FW code is inside the
169  * image because the GSC ROM will itself parse the headers to find it and load
170  * it.
171  * The GSC firmware header layout looks like this::
172  *
173  *	+================================================+
174  *	|  Layout Pointers                               |
175  *	|      ...                                       |
176  *	|      Boot1 offset  >---------------------------|------o
177  *	|      ...                                       |      |
178  *	+================================================+      |
179  *	                                                        |
180  *	+================================================+      |
181  *	|  BPDT header                                   |<-----o
182  *	+================================================+
183  *	|  BPDT entries[]                                |
184  *	|      entry1                                    |
185  *	|      ...                                       |
186  *	|      entryX                                    |
187  *	|          type == GSC_RBE                       |
188  *	|          offset  >-----------------------------|------o
189  *	|      ...                                       |      |
190  *	+================================================+      |
191  *	                                                        |
192  *	+================================================+      |
193  *	|  CPD Header                                    |<-----o
194  *	+================================================+
195  *	|  CPD entries[]                                 |
196  *	|      entry1                                    |
197  *	|      ...                                       |
198  *	|      entryX                                    |
199  *	|          "RBEP.man"                            |
200  *	|           ...                                  |
201  *	|           offset  >----------------------------|------o
202  *	|      ...                                       |      |
203  *	+================================================+      |
204  *	                                                        |
205  *	+================================================+      |
206  *	| Manifest Header                                |<-----o
207  *	|  ...                                           |
208  *	|  FW version                                    |
209  *	|  ...                                           |
210  *	|  Security version                              |
211  *	|  ...                                           |
212  *	+================================================+
213  */
214 
215 struct gsc_version {
216 	u16 major;
217 	u16 minor;
218 	u16 hotfix;
219 	u16 build;
220 } __packed;
221 
222 struct gsc_partition {
223 	u32 offset;
224 	u32 size;
225 } __packed;
226 
227 struct gsc_layout_pointers {
228 	u8 rom_bypass_vector[16];
229 
230 	/* size of this header section, not including ROM bypass vector */
231 	u16 size;
232 
233 	/*
234 	 * bit0: Backup copy of layout pointers exists
235 	 * bits1-15: reserved
236 	 */
237 	u8 flags;
238 
239 	u8 reserved;
240 
241 	u32 crc32;
242 
243 	struct gsc_partition datap;
244 	struct gsc_partition boot1;
245 	struct gsc_partition boot2;
246 	struct gsc_partition boot3;
247 	struct gsc_partition boot4;
248 	struct gsc_partition boot5;
249 	struct gsc_partition temp_pages;
250 } __packed;
251 
252 /* Boot partition structures */
253 struct gsc_bpdt_header {
254 	u32 signature;
255 #define GSC_BPDT_HEADER_SIGNATURE 0x000055AA
256 
257 	u16 descriptor_count; /* num of entries after the header */
258 
259 	u8 version;
260 	u8 configuration;
261 
262 	u32 crc32;
263 
264 	u32 build_version;
265 	struct gsc_version tool_version;
266 } __packed;
267 
268 struct gsc_bpdt_entry {
269 	/*
270 	 * Bits 0-15: BPDT entry type
271 	 * Bits 16-17: reserved
272 	 * Bit 18: code sub-partition
273 	 * Bits 19-31: reserved
274 	 */
275 	u32 type;
276 #define GSC_BPDT_ENTRY_TYPE_MASK GENMASK(15, 0)
277 #define GSC_BPDT_ENTRY_TYPE_GSC_RBE 0x1
278 
279 	u32 sub_partition_offset; /* from the base of the BPDT header */
280 	u32 sub_partition_size;
281 } __packed;
282 
283 /* Code partition directory (CPD) structures */
284 struct gsc_cpd_header_v2 {
285 	u32 header_marker;
286 #define GSC_CPD_HEADER_MARKER 0x44504324
287 
288 	u32 num_of_entries;
289 	u8 header_version;
290 	u8 entry_version;
291 	u8 header_length; /* in bytes */
292 	u8 flags;
293 	u32 partition_name;
294 	u32 crc32;
295 } __packed;
296 
297 struct gsc_cpd_entry {
298 	u8 name[12];
299 
300 	/*
301 	 * Bits 0-24: offset from the beginning of the code partition
302 	 * Bit 25: huffman compressed
303 	 * Bits 26-31: reserved
304 	 */
305 	u32 offset;
306 #define GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0)
307 #define GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25)
308 
309 	/*
310 	 * Module/Item length, in bytes. For Huffman-compressed modules, this
311 	 * refers to the uncompressed size. For software-compressed modules,
312 	 * this refers to the compressed size.
313 	 */
314 	u32 length;
315 
316 	u8 reserved[4];
317 } __packed;
318 
319 struct gsc_manifest_header {
320 	u32 header_type; /* 0x4 for manifest type */
321 	u32 header_length; /* in dwords */
322 	u32 header_version;
323 	u32 flags;
324 	u32 vendor;
325 	u32 date;
326 	u32 size; /* In dwords, size of entire manifest (header + extensions) */
327 	u32 header_id;
328 	u32 internal_data;
329 	struct gsc_version fw_version;
330 	u32 security_version;
331 	struct gsc_version meu_kit_version;
332 	u32 meu_manifest_version;
333 	u8 general_data[4];
334 	u8 reserved3[56];
335 	u32 modulus_size; /* in dwords */
336 	u32 exponent_size; /* in dwords */
337 } __packed;
338 
339 /**
340  * DOC: Late binding Firmware Layout
341  *
342  * The Late binding binary starts with FPT header, which contains locations
343  * of various partitions of the binary. Here we're interested in finding out
344  * manifest version. To the manifest version, we need to locate CPD header
345  * one of the entry in CPD header points to manifest header. Manifest header
346  * contains the version.
347  *
348  *      +================================================+
349  *      |  FPT Header                                    |
350  *      +================================================+
351  *      |  FPT entries[]                                 |
352  *      |      entry1                                    |
353  *      |      ...                                       |
354  *      |      entryX                                    |
355  *      |          "LTES"                                |
356  *      |          ...                                   |
357  *      |          offset  >-----------------------------|------o
358  *      +================================================+      |
359  *                                                              |
360  *      +================================================+      |
361  *      |  CPD Header                                    |<-----o
362  *      +================================================+
363  *      |  CPD entries[]                                 |
364  *      |      entry1                                    |
365  *      |      ...                                       |
366  *      |      entryX                                    |
367  *      |          "LTES.man"                            |
368  *      |           ...                                  |
369  *      |           offset  >----------------------------|------o
370  *      +================================================+      |
371  *                                                              |
372  *      +================================================+      |
373  *      |  Manifest Header                               |<-----o
374  *      |      ...                                       |
375  *      |      FW version                                |
376  *      |      ...                                       |
377  *      +================================================+
378  */
379 
380 /* FPT Headers */
381 struct csc_fpt_header {
382 	u32 header_marker;
383 #define CSC_FPT_HEADER_MARKER 0x54504624
384 	u32 num_of_entries;
385 	u8 header_version;
386 	u8 entry_version;
387 	u8 header_length; /* in bytes */
388 	u8 flags;
389 	u16 ticks_to_add;
390 	u16 tokens_to_add;
391 	u32 uma_size;
392 	u32 crc32;
393 	struct gsc_version fitc_version;
394 } __packed;
395 
396 struct csc_fpt_entry {
397 	u8 name[4]; /* partition name */
398 	u32 reserved1;
399 	u32 offset; /* offset from beginning of CSE region */
400 	u32 length; /* partition length in bytes */
401 	u32 reserved2[3];
402 	u32 partition_flags;
403 } __packed;
404 
405 #endif
406