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