Linux Audio

Check our new training course

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