xref: /linux/drivers/gpu/drm/xe/xe_uc_fw.c (revision a3a02a52bcfcbcc4a637d4b68bf1bc391c9fad02)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2022 Intel Corporation
4  */
5 
6 #include <linux/bitfield.h>
7 #include <linux/firmware.h>
8 
9 #include <drm/drm_managed.h>
10 
11 #include "regs/xe_guc_regs.h"
12 #include "xe_bo.h"
13 #include "xe_device_types.h"
14 #include "xe_force_wake.h"
15 #include "xe_gsc.h"
16 #include "xe_gt.h"
17 #include "xe_gt_printk.h"
18 #include "xe_map.h"
19 #include "xe_mmio.h"
20 #include "xe_module.h"
21 #include "xe_sriov.h"
22 #include "xe_uc_fw.h"
23 
24 /*
25  * List of required GuC and HuC binaries per-platform. They must be ordered
26  * based on platform, from newer to older.
27  *
28  * Versioning follows the guidelines from
29  * Documentation/driver-api/firmware/firmware-usage-guidelines.rst. There is a
30  * distinction for platforms being officially supported by the driver or not.
31  * Platforms not available publicly or not yet officially supported by the
32  * driver (under force-probe), use the mmp_ver(): the firmware autoselect logic
33  * will select the firmware from disk with filename that matches the full
34  * "mpp version", i.e. major.minor.patch. mmp_ver() should only be used for
35  * this case.
36  *
37  * For platforms officially supported by the driver, the filename always only
38  * ever contains the major version (GuC) or no version at all (HuC).
39  *
40  * After loading the file, the driver parses the versions embedded in the blob.
41  * The major version needs to match a major version supported by the driver (if
42  * any). The minor version is also checked and a notice emitted to the log if
43  * the version found is smaller than the version wanted. This is done only for
44  * informational purposes so users may have a chance to upgrade, but the driver
45  * still loads and use the older firmware.
46  *
47  * Examples:
48  *
49  *	1) Platform officially supported by i915 - using Tigerlake as example.
50  *	   Driver loads the following firmware blobs from disk:
51  *
52  *		- i915/tgl_guc_<major>.bin
53  *		- i915/tgl_huc.bin
54  *
55  *	   <major> number for GuC is checked that it matches the version inside
56  *	   the blob. <minor> version is checked and if smaller than the expected
57  *	   an info message is emitted about that.
58  *
59  *	1) XE_<FUTUREINTELPLATFORM>, still under require_force_probe. Using
60  *	   "wipplat" as a short-name. Driver loads the following firmware blobs
61  *	   from disk:
62  *
63  *		- xe/wipplat_guc_<major>.<minor>.<patch>.bin
64  *		- xe/wipplat_huc_<major>.<minor>.<patch>.bin
65  *
66  *	   <major> and <minor> are checked that they match the version inside
67  *	   the blob. Both of them need to match exactly what the driver is
68  *	   expecting, otherwise it fails.
69  *
70  *	3) Platform officially supported by xe and out of force-probe. Using
71  *	   "plat" as a short-name. Except for the different directory, the
72  *	   behavior is the same as (1). Driver loads the following firmware
73  *	   blobs from disk:
74  *
75  *		- xe/plat_guc_<major>.bin
76  *		- xe/plat_huc.bin
77  *
78  *	   <major> number for GuC is checked that it matches the version inside
79  *	   the blob. <minor> version is checked and if smaller than the expected
80  *	   an info message is emitted about that.
81  *
82  * For the platforms already released with a major version, they should never be
83  * removed from the table. Instead new entries with newer versions may be added
84  * before them, so they take precedence.
85  *
86  * TODO: Currently there's no fallback on major version. That's because xe
87  * driver only supports the one major version of each firmware in the table.
88  * This needs to be fixed when the major version of GuC is updated.
89  */
90 
91 struct uc_fw_entry {
92 	enum xe_platform platform;
93 	struct {
94 		const char *path;
95 		u16 major;
96 		u16 minor;
97 		u16 patch;
98 		bool full_ver_required;
99 	};
100 };
101 
102 struct fw_blobs_by_type {
103 	const struct uc_fw_entry *entries;
104 	u32 count;
105 };
106 
107 #define XE_GUC_FIRMWARE_DEFS(fw_def, mmp_ver, major_ver)			\
108 	fw_def(LUNARLAKE,	major_ver(xe,	guc,	lnl,	70, 19, 2))	\
109 	fw_def(METEORLAKE,	major_ver(i915,	guc,	mtl,	70, 19, 2))	\
110 	fw_def(DG2,		major_ver(i915,	guc,	dg2,	70, 19, 2))	\
111 	fw_def(DG1,		major_ver(i915,	guc,	dg1,	70, 19, 2))	\
112 	fw_def(ALDERLAKE_N,	major_ver(i915,	guc,	tgl,	70, 19, 2))	\
113 	fw_def(ALDERLAKE_P,	major_ver(i915,	guc,	adlp,	70, 19, 2))	\
114 	fw_def(ALDERLAKE_S,	major_ver(i915,	guc,	tgl,	70, 19, 2))	\
115 	fw_def(ROCKETLAKE,	major_ver(i915,	guc,	tgl,	70, 19, 2))	\
116 	fw_def(TIGERLAKE,	major_ver(i915,	guc,	tgl,	70, 19, 2))
117 
118 #define XE_HUC_FIRMWARE_DEFS(fw_def, mmp_ver, no_ver)		\
119 	fw_def(METEORLAKE,	no_ver(i915,	huc_gsc,	mtl))		\
120 	fw_def(DG1,		no_ver(i915,	huc,		dg1))		\
121 	fw_def(ALDERLAKE_P,	no_ver(i915,	huc,		tgl))		\
122 	fw_def(ALDERLAKE_S,	no_ver(i915,	huc,		tgl))		\
123 	fw_def(ROCKETLAKE,	no_ver(i915,	huc,		tgl))		\
124 	fw_def(TIGERLAKE,	no_ver(i915,	huc,		tgl))
125 
126 /* for the GSC FW we match the compatibility version and not the release one */
127 #define XE_GSC_FIRMWARE_DEFS(fw_def, major_ver)		\
128 	fw_def(METEORLAKE,	major_ver(i915,	gsc,	mtl,	1, 0, 0))
129 
130 #define MAKE_FW_PATH(dir__, uc__, shortname__, version__)			\
131 	__stringify(dir__) "/" __stringify(shortname__) "_" __stringify(uc__) version__ ".bin"
132 
133 #define fw_filename_mmp_ver(dir_, uc_, shortname_, a, b, c)			\
134 	MAKE_FW_PATH(dir_, uc_, shortname_, "_" __stringify(a ## . ## b ## . ## c))
135 #define fw_filename_major_ver(dir_, uc_, shortname_, a, b, c)			\
136 	MAKE_FW_PATH(dir_, uc_, shortname_, "_" __stringify(a))
137 #define fw_filename_no_ver(dir_, uc_, shortname_)				\
138 	MAKE_FW_PATH(dir_, uc_, shortname_, "")
139 
140 #define uc_fw_entry_mmp_ver(dir_, uc_, shortname_, a, b, c)			\
141 	{ fw_filename_mmp_ver(dir_, uc_, shortname_, a, b, c),			\
142 	  a, b, c, true }
143 #define uc_fw_entry_major_ver(dir_, uc_, shortname_, a, b, c)			\
144 	{ fw_filename_major_ver(dir_, uc_, shortname_, a, b, c),		\
145 	  a, b, c }
146 #define uc_fw_entry_no_ver(dir_, uc_, shortname_)				\
147 	{ fw_filename_no_ver(dir_, uc_, shortname_),				\
148 	  0, 0 }
149 
150 /* All blobs need to be declared via MODULE_FIRMWARE() */
151 #define XE_UC_MODULE_FIRMWARE(platform__, fw_filename)				\
152 	MODULE_FIRMWARE(fw_filename);
153 
154 #define XE_UC_FW_ENTRY(platform__, entry__)					\
155 	{									\
156 		.platform = XE_ ## platform__,					\
157 		entry__,							\
158 	},
159 
160 XE_GUC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE,
161 		     fw_filename_mmp_ver, fw_filename_major_ver)
162 XE_HUC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE,
163 		     fw_filename_mmp_ver, fw_filename_no_ver)
164 XE_GSC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE, fw_filename_major_ver)
165 
166 static struct xe_gt *
167 __uc_fw_to_gt(struct xe_uc_fw *uc_fw, enum xe_uc_fw_type type)
168 {
169 	XE_WARN_ON(type >= XE_UC_FW_NUM_TYPES);
170 
171 	switch (type) {
172 	case XE_UC_FW_TYPE_GUC:
173 		return container_of(uc_fw, struct xe_gt, uc.guc.fw);
174 	case XE_UC_FW_TYPE_HUC:
175 		return container_of(uc_fw, struct xe_gt, uc.huc.fw);
176 	case XE_UC_FW_TYPE_GSC:
177 		return container_of(uc_fw, struct xe_gt, uc.gsc.fw);
178 	default:
179 		return NULL;
180 	}
181 }
182 
183 static struct xe_gt *uc_fw_to_gt(struct xe_uc_fw *uc_fw)
184 {
185 	return __uc_fw_to_gt(uc_fw, uc_fw->type);
186 }
187 
188 static struct xe_device *uc_fw_to_xe(struct xe_uc_fw *uc_fw)
189 {
190 	return gt_to_xe(uc_fw_to_gt(uc_fw));
191 }
192 
193 static void
194 uc_fw_auto_select(struct xe_device *xe, struct xe_uc_fw *uc_fw)
195 {
196 	static const struct uc_fw_entry entries_guc[] = {
197 		XE_GUC_FIRMWARE_DEFS(XE_UC_FW_ENTRY,
198 				     uc_fw_entry_mmp_ver,
199 				     uc_fw_entry_major_ver)
200 	};
201 	static const struct uc_fw_entry entries_huc[] = {
202 		XE_HUC_FIRMWARE_DEFS(XE_UC_FW_ENTRY,
203 				     uc_fw_entry_mmp_ver,
204 				     uc_fw_entry_no_ver)
205 	};
206 	static const struct uc_fw_entry entries_gsc[] = {
207 		XE_GSC_FIRMWARE_DEFS(XE_UC_FW_ENTRY, uc_fw_entry_major_ver)
208 	};
209 	static const struct fw_blobs_by_type blobs_all[XE_UC_FW_NUM_TYPES] = {
210 		[XE_UC_FW_TYPE_GUC] = { entries_guc, ARRAY_SIZE(entries_guc) },
211 		[XE_UC_FW_TYPE_HUC] = { entries_huc, ARRAY_SIZE(entries_huc) },
212 		[XE_UC_FW_TYPE_GSC] = { entries_gsc, ARRAY_SIZE(entries_gsc) },
213 	};
214 	static const struct uc_fw_entry *entries;
215 	enum xe_platform p = xe->info.platform;
216 	u32 count;
217 	int i;
218 
219 	xe_assert(xe, uc_fw->type < ARRAY_SIZE(blobs_all));
220 	entries = blobs_all[uc_fw->type].entries;
221 	count = blobs_all[uc_fw->type].count;
222 
223 	for (i = 0; i < count && p <= entries[i].platform; i++) {
224 		if (p == entries[i].platform) {
225 			uc_fw->path = entries[i].path;
226 			uc_fw->versions.wanted.major = entries[i].major;
227 			uc_fw->versions.wanted.minor = entries[i].minor;
228 			uc_fw->versions.wanted.patch = entries[i].patch;
229 			uc_fw->full_ver_required = entries[i].full_ver_required;
230 
231 			if (uc_fw->type == XE_UC_FW_TYPE_GSC)
232 				uc_fw->versions.wanted_type = XE_UC_FW_VER_COMPATIBILITY;
233 			else
234 				uc_fw->versions.wanted_type = XE_UC_FW_VER_RELEASE;
235 
236 			break;
237 		}
238 	}
239 }
240 
241 static void
242 uc_fw_override(struct xe_uc_fw *uc_fw)
243 {
244 	char *path_override = NULL;
245 
246 	/* empty string disables, but it's not allowed for GuC */
247 	switch (uc_fw->type) {
248 	case XE_UC_FW_TYPE_GUC:
249 		if (xe_modparam.guc_firmware_path && *xe_modparam.guc_firmware_path)
250 			path_override = xe_modparam.guc_firmware_path;
251 		break;
252 	case XE_UC_FW_TYPE_HUC:
253 		path_override = xe_modparam.huc_firmware_path;
254 		break;
255 	case XE_UC_FW_TYPE_GSC:
256 		path_override = xe_modparam.gsc_firmware_path;
257 		break;
258 	default:
259 		break;
260 	}
261 
262 	if (path_override) {
263 		uc_fw->path = path_override;
264 		uc_fw->user_overridden = true;
265 	}
266 }
267 
268 /**
269  * xe_uc_fw_copy_rsa - copy fw RSA to buffer
270  *
271  * @uc_fw: uC firmware
272  * @dst: dst buffer
273  * @max_len: max number of bytes to copy
274  *
275  * Return: number of copied bytes.
276  */
277 size_t xe_uc_fw_copy_rsa(struct xe_uc_fw *uc_fw, void *dst, u32 max_len)
278 {
279 	struct xe_device *xe = uc_fw_to_xe(uc_fw);
280 	u32 size = min_t(u32, uc_fw->rsa_size, max_len);
281 
282 	xe_assert(xe, !(size % 4));
283 	xe_assert(xe, xe_uc_fw_is_available(uc_fw));
284 
285 	xe_map_memcpy_from(xe, dst, &uc_fw->bo->vmap,
286 			   xe_uc_fw_rsa_offset(uc_fw), size);
287 
288 	return size;
289 }
290 
291 static void uc_fw_fini(struct drm_device *drm, void *arg)
292 {
293 	struct xe_uc_fw *uc_fw = arg;
294 
295 	if (!xe_uc_fw_is_available(uc_fw))
296 		return;
297 
298 	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_SELECTED);
299 }
300 
301 static int guc_read_css_info(struct xe_uc_fw *uc_fw, struct uc_css_header *css)
302 {
303 	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
304 	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
305 	struct xe_uc_fw_version *compatibility = &uc_fw->versions.found[XE_UC_FW_VER_COMPATIBILITY];
306 
307 	xe_gt_assert(gt, uc_fw->type == XE_UC_FW_TYPE_GUC);
308 
309 	/* We don't support GuC releases older than 70.19 */
310 	if (release->major < 70 || (release->major == 70 && release->minor < 19)) {
311 		xe_gt_err(gt, "Unsupported GuC v%u.%u! v70.19 or newer is required\n",
312 			  release->major, release->minor);
313 		return -EINVAL;
314 	}
315 
316 	compatibility->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css->submission_version);
317 	compatibility->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css->submission_version);
318 	compatibility->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css->submission_version);
319 
320 	uc_fw->private_data_size = css->private_data_size;
321 
322 	return 0;
323 }
324 
325 int xe_uc_fw_check_version_requirements(struct xe_uc_fw *uc_fw)
326 {
327 	struct xe_device *xe = uc_fw_to_xe(uc_fw);
328 	struct xe_uc_fw_version *wanted = &uc_fw->versions.wanted;
329 	struct xe_uc_fw_version *found = &uc_fw->versions.found[uc_fw->versions.wanted_type];
330 
331 	/* Driver has no requirement on any version, any is good. */
332 	if (!wanted->major)
333 		return 0;
334 
335 	/*
336 	 * If full version is required, both major and minor should match.
337 	 * Otherwise, at least the major version.
338 	 */
339 	if (wanted->major != found->major ||
340 	    (uc_fw->full_ver_required &&
341 	     ((wanted->minor != found->minor) ||
342 	      (wanted->patch != found->patch)))) {
343 		drm_notice(&xe->drm, "%s firmware %s: unexpected version: %u.%u.%u != %u.%u.%u\n",
344 			   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
345 			   found->major, found->minor, found->patch,
346 			   wanted->major, wanted->minor, wanted->patch);
347 		goto fail;
348 	}
349 
350 	if (wanted->minor > found->minor ||
351 	    (wanted->minor == found->minor && wanted->patch > found->patch)) {
352 		drm_notice(&xe->drm, "%s firmware (%u.%u.%u) is recommended, but only (%u.%u.%u) was found in %s\n",
353 			   xe_uc_fw_type_repr(uc_fw->type),
354 			   wanted->major, wanted->minor, wanted->patch,
355 			   found->major, found->minor, found->patch,
356 			   uc_fw->path);
357 		drm_info(&xe->drm, "Consider updating your linux-firmware pkg or downloading from %s\n",
358 			 XE_UC_FIRMWARE_URL);
359 	}
360 
361 	return 0;
362 
363 fail:
364 	if (xe_uc_fw_is_overridden(uc_fw))
365 		return 0;
366 
367 	return -ENOEXEC;
368 }
369 
370 /* Refer to the "CSS-based Firmware Layout" documentation entry for details */
371 static int parse_css_header(struct xe_uc_fw *uc_fw, const void *fw_data, size_t fw_size)
372 {
373 	struct xe_device *xe = uc_fw_to_xe(uc_fw);
374 	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
375 	struct uc_css_header *css;
376 	size_t size;
377 
378 	/* Check the size of the blob before examining buffer contents */
379 	if (unlikely(fw_size < sizeof(struct uc_css_header))) {
380 		drm_warn(&xe->drm, "%s firmware %s: invalid size: %zu < %zu\n",
381 			 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
382 			 fw_size, sizeof(struct uc_css_header));
383 		return -ENODATA;
384 	}
385 
386 	css = (struct uc_css_header *)fw_data;
387 
388 	/* Check integrity of size values inside CSS header */
389 	size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw -
390 		css->exponent_size_dw) * sizeof(u32);
391 	if (unlikely(size != sizeof(struct uc_css_header))) {
392 		drm_warn(&xe->drm,
393 			 "%s firmware %s: unexpected header size: %zu != %zu\n",
394 			 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
395 			 fw_size, sizeof(struct uc_css_header));
396 		return -EPROTO;
397 	}
398 
399 	/* uCode size must calculated from other sizes */
400 	uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
401 
402 	/* now RSA */
403 	uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
404 
405 	/* At least, it should have header, uCode and RSA. Size of all three. */
406 	size = sizeof(struct uc_css_header) + uc_fw->ucode_size +
407 		uc_fw->rsa_size;
408 	if (unlikely(fw_size < size)) {
409 		drm_warn(&xe->drm, "%s firmware %s: invalid size: %zu < %zu\n",
410 			 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
411 			 fw_size, size);
412 		return -ENOEXEC;
413 	}
414 
415 	/* Get version numbers from the CSS header */
416 	release->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css->sw_version);
417 	release->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css->sw_version);
418 	release->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css->sw_version);
419 
420 	if (uc_fw->type == XE_UC_FW_TYPE_GUC)
421 		return guc_read_css_info(uc_fw, css);
422 
423 	return 0;
424 }
425 
426 static bool is_cpd_header(const void *data)
427 {
428 	const u32 *marker = data;
429 
430 	return *marker == GSC_CPD_HEADER_MARKER;
431 }
432 
433 static u32 entry_offset(const struct gsc_cpd_header_v2 *header, const char *name)
434 {
435 	const struct gsc_cpd_entry *entry;
436 	int i;
437 
438 	entry = (void *)header + header->header_length;
439 
440 	for (i = 0; i < header->num_of_entries; i++, entry++)
441 		if (strcmp(entry->name, name) == 0)
442 			return entry->offset & GSC_CPD_ENTRY_OFFSET_MASK;
443 
444 	return 0;
445 }
446 
447 /* Refer to the "GSC-based Firmware Layout" documentation entry for details */
448 static int parse_cpd_header(struct xe_uc_fw *uc_fw, const void *data, size_t size,
449 			    const char *manifest_entry, const char *css_entry)
450 {
451 	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
452 	struct xe_device *xe = gt_to_xe(gt);
453 	const struct gsc_cpd_header_v2 *header = data;
454 	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
455 	const struct gsc_manifest_header *manifest;
456 	size_t min_size = sizeof(*header);
457 	u32 offset;
458 
459 	/* manifest_entry is mandatory, css_entry is optional */
460 	xe_assert(xe, manifest_entry);
461 
462 	if (size < min_size || !is_cpd_header(header))
463 		return -ENOENT;
464 
465 	if (header->header_length < sizeof(struct gsc_cpd_header_v2)) {
466 		xe_gt_err(gt, "invalid CPD header length %u!\n", header->header_length);
467 		return -EINVAL;
468 	}
469 
470 	min_size = header->header_length + sizeof(struct gsc_cpd_entry) * header->num_of_entries;
471 	if (size < min_size) {
472 		xe_gt_err(gt, "FW too small! %zu < %zu\n", size, min_size);
473 		return -ENODATA;
474 	}
475 
476 	/* Look for the manifest first */
477 	offset = entry_offset(header, manifest_entry);
478 	if (!offset) {
479 		xe_gt_err(gt, "Failed to find %s manifest!\n",
480 			  xe_uc_fw_type_repr(uc_fw->type));
481 		return -ENODATA;
482 	}
483 
484 	min_size = offset + sizeof(struct gsc_manifest_header);
485 	if (size < min_size) {
486 		xe_gt_err(gt, "FW too small! %zu < %zu\n", size, min_size);
487 		return -ENODATA;
488 	}
489 
490 	manifest = data + offset;
491 
492 	release->major = manifest->fw_version.major;
493 	release->minor = manifest->fw_version.minor;
494 	release->patch = manifest->fw_version.hotfix;
495 
496 	if (uc_fw->type == XE_UC_FW_TYPE_GSC) {
497 		struct xe_gsc *gsc = container_of(uc_fw, struct xe_gsc, fw);
498 
499 		release->build = manifest->fw_version.build;
500 		gsc->security_version = manifest->security_version;
501 	}
502 
503 	/* then optionally look for the css header */
504 	if (css_entry) {
505 		int ret;
506 
507 		/*
508 		 * This section does not contain a CSS entry on DG2. We
509 		 * don't support DG2 HuC right now, so no need to handle
510 		 * it, just add a reminder in case that changes.
511 		 */
512 		xe_assert(xe, xe->info.platform != XE_DG2);
513 
514 		offset = entry_offset(header, css_entry);
515 
516 		/* the CSS header parser will check that the CSS header fits */
517 		if (offset > size) {
518 			xe_gt_err(gt, "FW too small! %zu < %u\n", size, offset);
519 			return -ENODATA;
520 		}
521 
522 		ret = parse_css_header(uc_fw, data + offset, size - offset);
523 		if (ret)
524 			return ret;
525 
526 		uc_fw->css_offset = offset;
527 	}
528 
529 	uc_fw->has_gsc_headers = true;
530 
531 	return 0;
532 }
533 
534 static int parse_gsc_layout(struct xe_uc_fw *uc_fw, const void *data, size_t size)
535 {
536 	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
537 	const struct gsc_layout_pointers *layout = data;
538 	const struct gsc_bpdt_header *bpdt_header = NULL;
539 	const struct gsc_bpdt_entry *bpdt_entry = NULL;
540 	size_t min_size = sizeof(*layout);
541 	int i;
542 
543 	if (size < min_size) {
544 		xe_gt_err(gt, "GSC FW too small! %zu < %zu\n", size, min_size);
545 		return -ENODATA;
546 	}
547 
548 	min_size = layout->boot1.offset + layout->boot1.size;
549 	if (size < min_size) {
550 		xe_gt_err(gt, "GSC FW too small for boot section! %zu < %zu\n",
551 			  size, min_size);
552 		return -ENODATA;
553 	}
554 
555 	min_size = sizeof(*bpdt_header);
556 	if (layout->boot1.size < min_size) {
557 		xe_gt_err(gt, "GSC FW boot section too small for BPDT header: %u < %zu\n",
558 			  layout->boot1.size, min_size);
559 		return -ENODATA;
560 	}
561 
562 	bpdt_header = data + layout->boot1.offset;
563 	if (bpdt_header->signature != GSC_BPDT_HEADER_SIGNATURE) {
564 		xe_gt_err(gt, "invalid signature for BPDT header: 0x%08x!\n",
565 			  bpdt_header->signature);
566 		return -EINVAL;
567 	}
568 
569 	min_size += sizeof(*bpdt_entry) * bpdt_header->descriptor_count;
570 	if (layout->boot1.size < min_size) {
571 		xe_gt_err(gt, "GSC FW boot section too small for BPDT entries: %u < %zu\n",
572 			  layout->boot1.size, min_size);
573 		return -ENODATA;
574 	}
575 
576 	bpdt_entry = (void *)bpdt_header + sizeof(*bpdt_header);
577 	for (i = 0; i < bpdt_header->descriptor_count; i++, bpdt_entry++) {
578 		if ((bpdt_entry->type & GSC_BPDT_ENTRY_TYPE_MASK) !=
579 		    GSC_BPDT_ENTRY_TYPE_GSC_RBE)
580 			continue;
581 
582 		min_size = bpdt_entry->sub_partition_offset;
583 
584 		/* the CPD header parser will check that the CPD header fits */
585 		if (layout->boot1.size < min_size) {
586 			xe_gt_err(gt, "GSC FW boot section too small for CPD offset: %u < %zu\n",
587 				  layout->boot1.size, min_size);
588 			return -ENODATA;
589 		}
590 
591 		return parse_cpd_header(uc_fw,
592 					(void *)bpdt_header + min_size,
593 					layout->boot1.size - min_size,
594 					"RBEP.man", NULL);
595 	}
596 
597 	xe_gt_err(gt, "couldn't find CPD header in GSC binary!\n");
598 	return -ENODATA;
599 }
600 
601 static int parse_headers(struct xe_uc_fw *uc_fw, const struct firmware *fw)
602 {
603 	int ret;
604 
605 	/*
606 	 * All GuC releases and older HuC ones use CSS headers, while newer HuC
607 	 * releases use GSC CPD headers.
608 	 */
609 	switch (uc_fw->type) {
610 	case XE_UC_FW_TYPE_GSC:
611 		return parse_gsc_layout(uc_fw, fw->data, fw->size);
612 	case XE_UC_FW_TYPE_HUC:
613 		ret = parse_cpd_header(uc_fw, fw->data, fw->size, "HUCP.man", "huc_fw");
614 		if (!ret || ret != -ENOENT)
615 			return ret;
616 		fallthrough;
617 	case XE_UC_FW_TYPE_GUC:
618 		return parse_css_header(uc_fw, fw->data, fw->size);
619 	default:
620 		return -EINVAL;
621 	}
622 
623 	return 0;
624 }
625 
626 #define print_uc_fw_version(p_, version_, prefix_, ...) \
627 do { \
628 	struct xe_uc_fw_version *ver_ = (version_); \
629 	if (ver_->build) \
630 		drm_printf(p_, prefix_ " version %u.%u.%u.%u\n", ##__VA_ARGS__, \
631 			   ver_->major, ver_->minor, \
632 			   ver_->patch, ver_->build); \
633 	else \
634 		drm_printf(p_, prefix_ " version %u.%u.%u\n", ##__VA_ARGS__, \
635 			  ver_->major, ver_->minor, ver_->patch); \
636 } while (0)
637 
638 static int uc_fw_request(struct xe_uc_fw *uc_fw, const struct firmware **firmware_p)
639 {
640 	struct xe_device *xe = uc_fw_to_xe(uc_fw);
641 	struct device *dev = xe->drm.dev;
642 	struct drm_printer p = drm_info_printer(dev);
643 	const struct firmware *fw = NULL;
644 	int err;
645 
646 	/*
647 	 * we use FIRMWARE_UNINITIALIZED to detect checks against uc_fw->status
648 	 * before we're looked at the HW caps to see if we have uc support
649 	 */
650 	BUILD_BUG_ON(XE_UC_FIRMWARE_UNINITIALIZED);
651 	xe_assert(xe, !uc_fw->status);
652 	xe_assert(xe, !uc_fw->path);
653 
654 	uc_fw_auto_select(xe, uc_fw);
655 
656 	if (IS_SRIOV_VF(xe)) {
657 		/* Only GuC/HuC are supported */
658 		if (uc_fw->type != XE_UC_FW_TYPE_GUC &&
659 		    uc_fw->type != XE_UC_FW_TYPE_HUC)
660 			uc_fw->path = NULL;
661 		/* VF will support only firmwares that driver can autoselect */
662 		xe_uc_fw_change_status(uc_fw, uc_fw->path ?
663 				       XE_UC_FIRMWARE_PRELOADED :
664 				       XE_UC_FIRMWARE_NOT_SUPPORTED);
665 		return 0;
666 	}
667 
668 	uc_fw_override(uc_fw);
669 
670 	xe_uc_fw_change_status(uc_fw, uc_fw->path ?
671 			       XE_UC_FIRMWARE_SELECTED :
672 			       XE_UC_FIRMWARE_NOT_SUPPORTED);
673 
674 	if (!xe_uc_fw_is_supported(uc_fw)) {
675 		if (uc_fw->type == XE_UC_FW_TYPE_GUC) {
676 			drm_err(&xe->drm, "No GuC firmware defined for platform\n");
677 			return -ENOENT;
678 		}
679 		return 0;
680 	}
681 
682 	/* an empty path means the firmware is disabled */
683 	if (!xe_device_uc_enabled(xe) || !(*uc_fw->path)) {
684 		xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_DISABLED);
685 		drm_dbg(&xe->drm, "%s disabled", xe_uc_fw_type_repr(uc_fw->type));
686 		return 0;
687 	}
688 
689 	err = request_firmware(&fw, uc_fw->path, dev);
690 	if (err)
691 		goto fail;
692 
693 	err = parse_headers(uc_fw, fw);
694 	if (err)
695 		goto fail;
696 
697 	print_uc_fw_version(&p,
698 			    &uc_fw->versions.found[XE_UC_FW_VER_RELEASE],
699 			    "Using %s firmware from %s",
700 			    xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
701 
702 	/* for GSC FW we want the compatibility version, which we query after load */
703 	if (uc_fw->type != XE_UC_FW_TYPE_GSC) {
704 		err = xe_uc_fw_check_version_requirements(uc_fw);
705 		if (err)
706 			goto fail;
707 	}
708 
709 	*firmware_p = fw;
710 
711 	return 0;
712 
713 fail:
714 	xe_uc_fw_change_status(uc_fw, err == -ENOENT ?
715 			       XE_UC_FIRMWARE_MISSING :
716 			       XE_UC_FIRMWARE_ERROR);
717 
718 	drm_notice(&xe->drm, "%s firmware %s: fetch failed with error %d\n",
719 		   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);
720 	drm_info(&xe->drm, "%s firmware(s) can be downloaded from %s\n",
721 		 xe_uc_fw_type_repr(uc_fw->type), XE_UC_FIRMWARE_URL);
722 
723 	release_firmware(fw);		/* OK even if fw is NULL */
724 
725 	return err;
726 }
727 
728 static void uc_fw_release(const struct firmware *fw)
729 {
730 	release_firmware(fw);
731 }
732 
733 static int uc_fw_copy(struct xe_uc_fw *uc_fw, const void *data, size_t size, u32 flags)
734 {
735 	struct xe_device *xe = uc_fw_to_xe(uc_fw);
736 	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
737 	struct xe_tile *tile = gt_to_tile(gt);
738 	struct xe_bo *obj;
739 	int err;
740 
741 	obj = xe_managed_bo_create_from_data(xe, tile, data, size, flags);
742 	if (IS_ERR(obj)) {
743 		drm_notice(&xe->drm, "%s firmware %s: failed to create / populate bo",
744 			   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
745 		err = PTR_ERR(obj);
746 		goto fail;
747 	}
748 
749 	uc_fw->bo = obj;
750 	uc_fw->size = size;
751 
752 	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_AVAILABLE);
753 
754 	err = drmm_add_action_or_reset(&xe->drm, uc_fw_fini, uc_fw);
755 	if (err)
756 		goto fail;
757 
758 	return 0;
759 
760 fail:
761 	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_ERROR);
762 	drm_notice(&xe->drm, "%s firmware %s: copy failed with error %d\n",
763 		   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);
764 
765 	return err;
766 }
767 
768 int xe_uc_fw_init(struct xe_uc_fw *uc_fw)
769 {
770 	const struct firmware *fw = NULL;
771 	int err;
772 
773 	err = uc_fw_request(uc_fw, &fw);
774 	if (err)
775 		return err;
776 
777 	/* no error and no firmware means nothing to copy */
778 	if (!fw)
779 		return 0;
780 
781 	err = uc_fw_copy(uc_fw, fw->data, fw->size,
782 			 XE_BO_FLAG_SYSTEM | XE_BO_FLAG_GGTT |
783 			 XE_BO_FLAG_GGTT_INVALIDATE);
784 
785 	uc_fw_release(fw);
786 
787 	return err;
788 }
789 
790 static u32 uc_fw_ggtt_offset(struct xe_uc_fw *uc_fw)
791 {
792 	return xe_bo_ggtt_addr(uc_fw->bo);
793 }
794 
795 static int uc_fw_xfer(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags)
796 {
797 	struct xe_device *xe = uc_fw_to_xe(uc_fw);
798 	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
799 	u64 src_offset;
800 	u32 dma_ctrl;
801 	int ret;
802 
803 	xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT);
804 
805 	/* Set the source address for the uCode */
806 	src_offset = uc_fw_ggtt_offset(uc_fw) + uc_fw->css_offset;
807 	xe_mmio_write32(gt, DMA_ADDR_0_LOW, lower_32_bits(src_offset));
808 	xe_mmio_write32(gt, DMA_ADDR_0_HIGH,
809 			upper_32_bits(src_offset) | DMA_ADDRESS_SPACE_GGTT);
810 
811 	/* Set the DMA destination */
812 	xe_mmio_write32(gt, DMA_ADDR_1_LOW, offset);
813 	xe_mmio_write32(gt, DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
814 
815 	/*
816 	 * Set the transfer size. The header plus uCode will be copied to WOPCM
817 	 * via DMA, excluding any other components
818 	 */
819 	xe_mmio_write32(gt, DMA_COPY_SIZE,
820 			sizeof(struct uc_css_header) + uc_fw->ucode_size);
821 
822 	/* Start the DMA */
823 	xe_mmio_write32(gt, DMA_CTRL,
824 			_MASKED_BIT_ENABLE(dma_flags | START_DMA));
825 
826 	/* Wait for DMA to finish */
827 	ret = xe_mmio_wait32(gt, DMA_CTRL, START_DMA, 0, 100000, &dma_ctrl,
828 			     false);
829 	if (ret)
830 		drm_err(&xe->drm, "DMA for %s fw failed, DMA_CTRL=%u\n",
831 			xe_uc_fw_type_repr(uc_fw->type), dma_ctrl);
832 
833 	/* Disable the bits once DMA is over */
834 	xe_mmio_write32(gt, DMA_CTRL, _MASKED_BIT_DISABLE(dma_flags));
835 
836 	return ret;
837 }
838 
839 int xe_uc_fw_upload(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags)
840 {
841 	struct xe_device *xe = uc_fw_to_xe(uc_fw);
842 	int err;
843 
844 	/* make sure the status was cleared the last time we reset the uc */
845 	xe_assert(xe, !xe_uc_fw_is_loaded(uc_fw));
846 
847 	if (!xe_uc_fw_is_loadable(uc_fw))
848 		return -ENOEXEC;
849 
850 	/* Call custom loader */
851 	err = uc_fw_xfer(uc_fw, offset, dma_flags);
852 	if (err)
853 		goto fail;
854 
855 	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_TRANSFERRED);
856 	return 0;
857 
858 fail:
859 	drm_err(&xe->drm, "Failed to load %s firmware %s (%d)\n",
860 		xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
861 		err);
862 	xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_LOAD_FAIL);
863 	return err;
864 }
865 
866 static const char *version_type_repr(enum xe_uc_fw_version_types type)
867 {
868 	switch (type) {
869 	case XE_UC_FW_VER_RELEASE:
870 		return "release";
871 	case XE_UC_FW_VER_COMPATIBILITY:
872 		return "compatibility";
873 	default:
874 		return "Unknown version type";
875 	}
876 }
877 
878 void xe_uc_fw_print(struct xe_uc_fw *uc_fw, struct drm_printer *p)
879 {
880 	int i;
881 
882 	drm_printf(p, "%s firmware: %s\n",
883 		   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
884 	drm_printf(p, "\tstatus: %s\n",
885 		   xe_uc_fw_status_repr(uc_fw->status));
886 
887 	print_uc_fw_version(p, &uc_fw->versions.wanted, "\twanted %s",
888 			    version_type_repr(uc_fw->versions.wanted_type));
889 
890 	for (i = 0; i < XE_UC_FW_VER_TYPE_COUNT; i++) {
891 		struct xe_uc_fw_version *ver = &uc_fw->versions.found[i];
892 
893 		if (ver->major)
894 			print_uc_fw_version(p, ver, "\tfound %s",
895 					    version_type_repr(i));
896 	}
897 
898 	if (uc_fw->ucode_size)
899 		drm_printf(p, "\tuCode: %u bytes\n", uc_fw->ucode_size);
900 	if (uc_fw->rsa_size)
901 		drm_printf(p, "\tRSA: %u bytes\n", uc_fw->rsa_size);
902 }
903