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
47struct uc_css_rsa_info {
48 u32 key_size_dw;
49 u32 modulus_size_dw;
50 u32 exponent_size_dw;
51} __packed;
52
53struct 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
80struct 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;
104static_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
215struct gsc_version {
216 u16 major;
217 u16 minor;
218 u16 hotfix;
219 u16 build;
220} __packed;
221
222struct gsc_partition {
223 u32 offset;
224 u32 size;
225} __packed;
226
227struct 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 */
253struct 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
268struct 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 */
284struct 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
297struct 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
319struct 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 */
381struct 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
396struct 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

source code of linux/drivers/gpu/drm/xe/xe_uc_fw_abi.h