File Index
Files and directories
Sign in
FILE

xe_uc_fw.c

File preview with syntax highlighting.

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