1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2016-2019 Intel Corporation
4  */
5 
6 #include <linux/bitfield.h>
7 #include <linux/firmware.h>
8 #include <linux/highmem.h>
9 
10 #include <drm/drm_cache.h>
11 #include <drm/drm_print.h>
12 
13 #include "gem/i915_gem_lmem.h"
14 #include "gt/intel_gt_print.h"
15 #include "intel_gsc_binary_headers.h"
16 #include "intel_gsc_fw.h"
17 #include "intel_uc_fw.h"
18 #include "intel_uc_fw_abi.h"
19 #include "i915_drv.h"
20 #include "i915_reg.h"
21 
22 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
23 #define UNEXPECTED	gt_probe_error
24 #else
25 #define UNEXPECTED	gt_notice
26 #endif
27 
28 static inline struct intel_gt *
29 ____uc_fw_to_gt(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type)
30 {
31 	GEM_BUG_ON(type >= INTEL_UC_FW_NUM_TYPES);
32 
33 	switch (type) {
34 	case INTEL_UC_FW_TYPE_GUC:
35 		return container_of(uc_fw, struct intel_gt, uc.guc.fw);
36 	case INTEL_UC_FW_TYPE_HUC:
37 		return container_of(uc_fw, struct intel_gt, uc.huc.fw);
38 	case INTEL_UC_FW_TYPE_GSC:
39 		return container_of(uc_fw, struct intel_gt, uc.gsc.fw);
40 	}
41 
42 	return NULL;
43 }
44 
45 static inline struct intel_gt *__uc_fw_to_gt(struct intel_uc_fw *uc_fw)
46 {
47 	GEM_BUG_ON(uc_fw->status == INTEL_UC_FIRMWARE_UNINITIALIZED);
48 	return ____uc_fw_to_gt(uc_fw, uc_fw->type);
49 }
50 
51 #ifdef CONFIG_DRM_I915_DEBUG_GUC
52 void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
53 			       enum intel_uc_fw_status status)
54 {
55 	uc_fw->__status =  status;
56 	gt_dbg(__uc_fw_to_gt(uc_fw), "%s firmware -> %s\n",
57 	       intel_uc_fw_type_repr(uc_fw->type),
58 	       status == INTEL_UC_FIRMWARE_SELECTED ?
59 	       uc_fw->file_selected.path : intel_uc_fw_status_repr(status));
60 }
61 #endif
62 
63 /*
64  * List of required GuC and HuC binaries per-platform.
65  * Must be ordered based on platform + revid, from newer to older.
66  *
67  * Note that RKL and ADL-S have the same GuC/HuC device ID's and use the same
68  * firmware as TGL.
69  *
70  * Version numbers:
71  * Originally, the driver required an exact match major/minor/patch furmware
72  * file and only supported that one version for any given platform. However,
73  * the new direction from upstream is to be backwards compatible with all
74  * prior releases and to be as flexible as possible as to what firmware is
75  * loaded.
76  *
77  * For GuC, the major version number signifies a backwards breaking API change.
78  * So, new format GuC firmware files are labelled by their major version only.
79  * For HuC, there is no KMD interaction, hence no version matching requirement.
80  * So, new format HuC firmware files have no version number at all.
81  *
82  * All of which means that the table below must keep all old format files with
83  * full three point version number. But newer files have reduced requirements.
84  * Having said that, the driver still needs to track the minor version number
85  * for GuC at least. As it is useful to report to the user that they are not
86  * running with a recent enough version for all KMD supported features,
87  * security fixes, etc. to be enabled.
88  */
89 #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
90 	fw_def(METEORLAKE,   0, guc_maj(mtl,  70, 6, 6)) \
91 	fw_def(DG2,          0, guc_maj(dg2,  70, 5, 1)) \
92 	fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5, 1)) \
93 	fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 70, 1, 1)) \
94 	fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 69, 0, 3)) \
95 	fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5, 1)) \
96 	fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  70, 1, 1)) \
97 	fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  69, 0, 3)) \
98 	fw_def(DG1,          0, guc_maj(dg1,  70, 5, 1)) \
99 	fw_def(ROCKETLAKE,   0, guc_mmp(tgl,  70, 1, 1)) \
100 	fw_def(TIGERLAKE,    0, guc_mmp(tgl,  70, 1, 1)) \
101 	fw_def(JASPERLAKE,   0, guc_mmp(ehl,  70, 1, 1)) \
102 	fw_def(ELKHARTLAKE,  0, guc_mmp(ehl,  70, 1, 1)) \
103 	fw_def(ICELAKE,      0, guc_mmp(icl,  70, 1, 1)) \
104 	fw_def(COMETLAKE,    5, guc_mmp(cml,  70, 1, 1)) \
105 	fw_def(COMETLAKE,    0, guc_mmp(kbl,  70, 1, 1)) \
106 	fw_def(COFFEELAKE,   0, guc_mmp(kbl,  70, 1, 1)) \
107 	fw_def(GEMINILAKE,   0, guc_mmp(glk,  70, 1, 1)) \
108 	fw_def(KABYLAKE,     0, guc_mmp(kbl,  70, 1, 1)) \
109 	fw_def(BROXTON,      0, guc_mmp(bxt,  70, 1, 1)) \
110 	fw_def(SKYLAKE,      0, guc_mmp(skl,  70, 1, 1))
111 
112 #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_raw, huc_mmp, huc_gsc) \
113 	fw_def(METEORLAKE,   0, huc_gsc(mtl)) \
114 	fw_def(DG2,          0, huc_gsc(dg2)) \
115 	fw_def(ALDERLAKE_P,  0, huc_raw(tgl)) \
116 	fw_def(ALDERLAKE_P,  0, huc_mmp(tgl,  7, 9, 3)) \
117 	fw_def(ALDERLAKE_S,  0, huc_raw(tgl)) \
118 	fw_def(ALDERLAKE_S,  0, huc_mmp(tgl,  7, 9, 3)) \
119 	fw_def(DG1,          0, huc_raw(dg1)) \
120 	fw_def(ROCKETLAKE,   0, huc_mmp(tgl,  7, 9, 3)) \
121 	fw_def(TIGERLAKE,    0, huc_mmp(tgl,  7, 9, 3)) \
122 	fw_def(JASPERLAKE,   0, huc_mmp(ehl,  9, 0, 0)) \
123 	fw_def(ELKHARTLAKE,  0, huc_mmp(ehl,  9, 0, 0)) \
124 	fw_def(ICELAKE,      0, huc_mmp(icl,  9, 0, 0)) \
125 	fw_def(COMETLAKE,    5, huc_mmp(cml,  4, 0, 0)) \
126 	fw_def(COMETLAKE,    0, huc_mmp(kbl,  4, 0, 0)) \
127 	fw_def(COFFEELAKE,   0, huc_mmp(kbl,  4, 0, 0)) \
128 	fw_def(GEMINILAKE,   0, huc_mmp(glk,  4, 0, 0)) \
129 	fw_def(KABYLAKE,     0, huc_mmp(kbl,  4, 0, 0)) \
130 	fw_def(BROXTON,      0, huc_mmp(bxt,  2, 0, 0)) \
131 	fw_def(SKYLAKE,      0, huc_mmp(skl,  2, 0, 0))
132 
133 /*
134  * Set of macros for producing a list of filenames from the above table.
135  */
136 #define __MAKE_UC_FW_PATH_BLANK(prefix_, name_) \
137 	"i915/" \
138 	__stringify(prefix_) "_" name_ ".bin"
139 
140 #define __MAKE_UC_FW_PATH_MAJOR(prefix_, name_, major_) \
141 	"i915/" \
142 	__stringify(prefix_) "_" name_ "_" \
143 	__stringify(major_) ".bin"
144 
145 #define __MAKE_UC_FW_PATH_MMP(prefix_, name_, major_, minor_, patch_) \
146 	"i915/" \
147 	__stringify(prefix_) "_" name_  "_" \
148 	__stringify(major_) "." \
149 	__stringify(minor_) "." \
150 	__stringify(patch_) ".bin"
151 
152 /* Minor for internal driver use, not part of file name */
153 #define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_) \
154 	__MAKE_UC_FW_PATH_MAJOR(prefix_, "guc", major_)
155 
156 #define MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
157 	__MAKE_UC_FW_PATH_MMP(prefix_, "guc", major_, minor_, patch_)
158 
159 #define MAKE_HUC_FW_PATH_BLANK(prefix_) \
160 	__MAKE_UC_FW_PATH_BLANK(prefix_, "huc")
161 
162 #define MAKE_HUC_FW_PATH_GSC(prefix_) \
163 	__MAKE_UC_FW_PATH_BLANK(prefix_, "huc_gsc")
164 
165 #define MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
166 	__MAKE_UC_FW_PATH_MMP(prefix_, "huc", major_, minor_, patch_)
167 
168 /*
169  * All blobs need to be declared via MODULE_FIRMWARE().
170  * This first expansion of the table macros is solely to provide
171  * that declaration.
172  */
173 #define INTEL_UC_MODULE_FW(platform_, revid_, uc_) \
174 	MODULE_FIRMWARE(uc_);
175 
176 INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH_MAJOR, MAKE_GUC_FW_PATH_MMP)
177 INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, MAKE_HUC_FW_PATH_MMP, MAKE_HUC_FW_PATH_GSC)
178 
179 /*
180  * The next expansion of the table macros (in __uc_fw_auto_select below) provides
181  * actual data structures with both the filename and the version information.
182  * These structure arrays are then iterated over to the list of suitable files
183  * for the current platform and to then attempt to load those files, in the order
184  * listed, until one is successfully found.
185  */
186 struct __packed uc_fw_blob {
187 	const char *path;
188 	bool legacy;
189 	u8 major;
190 	u8 minor;
191 	u8 patch;
192 	bool has_gsc_headers;
193 };
194 
195 #define UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
196 	.major = major_, \
197 	.minor = minor_, \
198 	.patch = patch_, \
199 	.path = path_,
200 
201 #define UC_FW_BLOB_NEW(major_, minor_, patch_, gsc_, path_) \
202 	{ UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
203 	  .legacy = false, .has_gsc_headers = gsc_ }
204 
205 #define UC_FW_BLOB_OLD(major_, minor_, patch_, path_) \
206 	{ UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
207 	  .legacy = true }
208 
209 #define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
210 	UC_FW_BLOB_NEW(major_, minor_, patch_, false, \
211 		       MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_))
212 
213 #define GUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_) \
214 	UC_FW_BLOB_OLD(major_, minor_, patch_, \
215 		       MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_))
216 
217 #define HUC_FW_BLOB(prefix_) \
218 	UC_FW_BLOB_NEW(0, 0, 0, false, MAKE_HUC_FW_PATH_BLANK(prefix_))
219 
220 #define HUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_) \
221 	UC_FW_BLOB_OLD(major_, minor_, patch_, \
222 		       MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_))
223 
224 #define HUC_FW_BLOB_GSC(prefix_) \
225 	UC_FW_BLOB_NEW(0, 0, 0, true, MAKE_HUC_FW_PATH_GSC(prefix_))
226 
227 struct __packed uc_fw_platform_requirement {
228 	enum intel_platform p;
229 	u8 rev; /* first platform rev using this FW */
230 	const struct uc_fw_blob blob;
231 };
232 
233 #define MAKE_FW_LIST(platform_, revid_, uc_) \
234 { \
235 	.p = INTEL_##platform_, \
236 	.rev = revid_, \
237 	.blob = uc_, \
238 },
239 
240 struct fw_blobs_by_type {
241 	const struct uc_fw_platform_requirement *blobs;
242 	u32 count;
243 };
244 
245 static const struct uc_fw_platform_requirement blobs_guc[] = {
246 	INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, GUC_FW_BLOB_MMP)
247 };
248 
249 static const struct uc_fw_platform_requirement blobs_huc[] = {
250 	INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)
251 };
252 
253 static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
254 	[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
255 	[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
256 };
257 
258 static void
259 __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
260 {
261 	const struct uc_fw_platform_requirement *fw_blobs;
262 	enum intel_platform p = INTEL_INFO(i915)->platform;
263 	u32 fw_count;
264 	u8 rev = INTEL_REVID(i915);
265 	int i;
266 	bool found;
267 
268 	/*
269 	 * GSC FW support is still not fully in place, so we're not defining
270 	 * the FW blob yet because we don't want the driver to attempt to load
271 	 * it until we're ready for it.
272 	 */
273 	if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
274 		return;
275 
276 	/*
277 	 * The only difference between the ADL GuC FWs is the HWConfig support.
278 	 * ADL-N does not support HWConfig, so we should use the same binary as
279 	 * ADL-S, otherwise the GuC might attempt to fetch a config table that
280 	 * does not exist.
281 	 */
282 	if (IS_ADLP_N(i915))
283 		p = INTEL_ALDERLAKE_S;
284 
285 	GEM_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all));
286 	fw_blobs = blobs_all[uc_fw->type].blobs;
287 	fw_count = blobs_all[uc_fw->type].count;
288 
289 	found = false;
290 	for (i = 0; i < fw_count && p <= fw_blobs[i].p; i++) {
291 		const struct uc_fw_blob *blob = &fw_blobs[i].blob;
292 
293 		if (p != fw_blobs[i].p)
294 			continue;
295 
296 		if (rev < fw_blobs[i].rev)
297 			continue;
298 
299 		if (uc_fw->file_selected.path) {
300 			/*
301 			 * Continuing an earlier search after a found blob failed to load.
302 			 * Once the previously chosen path has been found, clear it out
303 			 * and let the search continue from there.
304 			 */
305 			if (uc_fw->file_selected.path == blob->path)
306 				uc_fw->file_selected.path = NULL;
307 
308 			continue;
309 		}
310 
311 		uc_fw->file_selected.path = blob->path;
312 		uc_fw->file_wanted.path = blob->path;
313 		uc_fw->file_wanted.ver.major = blob->major;
314 		uc_fw->file_wanted.ver.minor = blob->minor;
315 		uc_fw->file_wanted.ver.patch = blob->patch;
316 		uc_fw->has_gsc_headers = blob->has_gsc_headers;
317 		found = true;
318 		break;
319 	}
320 
321 	if (!found && uc_fw->file_selected.path) {
322 		/* Failed to find a match for the last attempt?! */
323 		uc_fw->file_selected.path = NULL;
324 	}
325 }
326 
327 static bool validate_fw_table_type(struct drm_i915_private *i915, enum intel_uc_fw_type type)
328 {
329 	const struct uc_fw_platform_requirement *fw_blobs;
330 	u32 fw_count;
331 	int i, j;
332 
333 	if (type >= ARRAY_SIZE(blobs_all)) {
334 		drm_err(&i915->drm, "No blob array for %s\n", intel_uc_fw_type_repr(type));
335 		return false;
336 	}
337 
338 	fw_blobs = blobs_all[type].blobs;
339 	fw_count = blobs_all[type].count;
340 
341 	if (!fw_count)
342 		return true;
343 
344 	/* make sure the list is ordered as expected */
345 	for (i = 1; i < fw_count; i++) {
346 		/* Versionless file names must be unique per platform: */
347 		for (j = i + 1; j < fw_count; j++) {
348 			/* Same platform? */
349 			if (fw_blobs[i].p != fw_blobs[j].p)
350 				continue;
351 
352 			if (fw_blobs[i].blob.path != fw_blobs[j].blob.path)
353 				continue;
354 
355 			drm_err(&i915->drm, "Duplicate %s blobs: %s r%u %s%d.%d.%d [%s] matches %s%d.%d.%d [%s]\n",
356 				intel_uc_fw_type_repr(type),
357 				intel_platform_name(fw_blobs[j].p), fw_blobs[j].rev,
358 				fw_blobs[j].blob.legacy ? "L" : "v",
359 				fw_blobs[j].blob.major, fw_blobs[j].blob.minor,
360 				fw_blobs[j].blob.patch, fw_blobs[j].blob.path,
361 				fw_blobs[i].blob.legacy ? "L" : "v",
362 				fw_blobs[i].blob.major, fw_blobs[i].blob.minor,
363 				fw_blobs[i].blob.patch, fw_blobs[i].blob.path);
364 		}
365 
366 		/* Next platform is good: */
367 		if (fw_blobs[i].p < fw_blobs[i - 1].p)
368 			continue;
369 
370 		/* Next platform revision is good: */
371 		if (fw_blobs[i].p == fw_blobs[i - 1].p &&
372 		    fw_blobs[i].rev < fw_blobs[i - 1].rev)
373 			continue;
374 
375 		/* Platform/revision must be in order: */
376 		if (fw_blobs[i].p != fw_blobs[i - 1].p ||
377 		    fw_blobs[i].rev != fw_blobs[i - 1].rev)
378 			goto bad;
379 
380 		/* Next major version is good: */
381 		if (fw_blobs[i].blob.major < fw_blobs[i - 1].blob.major)
382 			continue;
383 
384 		/* New must be before legacy: */
385 		if (!fw_blobs[i].blob.legacy && fw_blobs[i - 1].blob.legacy)
386 			goto bad;
387 
388 		/* New to legacy also means 0.0 to X.Y (HuC), or X.0 to X.Y (GuC) */
389 		if (fw_blobs[i].blob.legacy && !fw_blobs[i - 1].blob.legacy) {
390 			if (!fw_blobs[i - 1].blob.major)
391 				continue;
392 
393 			if (fw_blobs[i].blob.major == fw_blobs[i - 1].blob.major)
394 				continue;
395 		}
396 
397 		/* Major versions must be in order: */
398 		if (fw_blobs[i].blob.major != fw_blobs[i - 1].blob.major)
399 			goto bad;
400 
401 		/* Next minor version is good: */
402 		if (fw_blobs[i].blob.minor < fw_blobs[i - 1].blob.minor)
403 			continue;
404 
405 		/* Minor versions must be in order: */
406 		if (fw_blobs[i].blob.minor != fw_blobs[i - 1].blob.minor)
407 			goto bad;
408 
409 		/* Patch versions must be in order and unique: */
410 		if (fw_blobs[i].blob.patch < fw_blobs[i - 1].blob.patch)
411 			continue;
412 
413 bad:
414 		drm_err(&i915->drm, "Invalid %s blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n",
415 			intel_uc_fw_type_repr(type),
416 			intel_platform_name(fw_blobs[i - 1].p), fw_blobs[i - 1].rev,
417 			fw_blobs[i - 1].blob.legacy ? "L" : "v",
418 			fw_blobs[i - 1].blob.major,
419 			fw_blobs[i - 1].blob.minor,
420 			fw_blobs[i - 1].blob.patch,
421 			intel_platform_name(fw_blobs[i].p), fw_blobs[i].rev,
422 			fw_blobs[i].blob.legacy ? "L" : "v",
423 			fw_blobs[i].blob.major,
424 			fw_blobs[i].blob.minor,
425 			fw_blobs[i].blob.patch);
426 		return false;
427 	}
428 
429 	return true;
430 }
431 
432 static const char *__override_guc_firmware_path(struct drm_i915_private *i915)
433 {
434 	if (i915->params.enable_guc & ENABLE_GUC_MASK)
435 		return i915->params.guc_firmware_path;
436 	return "";
437 }
438 
439 static const char *__override_huc_firmware_path(struct drm_i915_private *i915)
440 {
441 	if (i915->params.enable_guc & ENABLE_GUC_LOAD_HUC)
442 		return i915->params.huc_firmware_path;
443 	return "";
444 }
445 
446 static const char *__override_gsc_firmware_path(struct drm_i915_private *i915)
447 {
448 	return i915->params.gsc_firmware_path;
449 }
450 
451 static void __uc_fw_user_override(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
452 {
453 	const char *path = NULL;
454 
455 	switch (uc_fw->type) {
456 	case INTEL_UC_FW_TYPE_GUC:
457 		path = __override_guc_firmware_path(i915);
458 		break;
459 	case INTEL_UC_FW_TYPE_HUC:
460 		path = __override_huc_firmware_path(i915);
461 		break;
462 	case INTEL_UC_FW_TYPE_GSC:
463 		path = __override_gsc_firmware_path(i915);
464 		break;
465 	}
466 
467 	if (unlikely(path)) {
468 		uc_fw->file_selected.path = path;
469 		uc_fw->user_overridden = true;
470 	}
471 }
472 
473 void intel_uc_fw_version_from_gsc_manifest(struct intel_uc_fw_ver *ver,
474 					   const void *data)
475 {
476 	const struct intel_gsc_manifest_header *manifest = data;
477 
478 	ver->major = manifest->fw_version.major;
479 	ver->minor = manifest->fw_version.minor;
480 	ver->patch = manifest->fw_version.hotfix;
481 	ver->build = manifest->fw_version.build;
482 }
483 
484 /**
485  * intel_uc_fw_init_early - initialize the uC object and select the firmware
486  * @uc_fw: uC firmware
487  * @type: type of uC
488  * @needs_ggtt_mapping: whether the FW needs to be GGTT mapped for loading
489  *
490  * Initialize the state of our uC object and relevant tracking and select the
491  * firmware to fetch and load.
492  */
493 void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
494 			    enum intel_uc_fw_type type,
495 			    bool needs_ggtt_mapping)
496 {
497 	struct intel_gt *gt = ____uc_fw_to_gt(uc_fw, type);
498 	struct drm_i915_private *i915 = gt->i915;
499 
500 	/*
501 	 * we use FIRMWARE_UNINITIALIZED to detect checks against uc_fw->status
502 	 * before we're looked at the HW caps to see if we have uc support
503 	 */
504 	BUILD_BUG_ON(INTEL_UC_FIRMWARE_UNINITIALIZED);
505 	GEM_BUG_ON(uc_fw->status);
506 	GEM_BUG_ON(uc_fw->file_selected.path);
507 
508 	uc_fw->type = type;
509 	uc_fw->needs_ggtt_mapping = needs_ggtt_mapping;
510 
511 	if (HAS_GT_UC(i915)) {
512 		if (!validate_fw_table_type(i915, type)) {
513 			gt->uc.fw_table_invalid = true;
514 			intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
515 			return;
516 		}
517 
518 		__uc_fw_auto_select(i915, uc_fw);
519 		__uc_fw_user_override(i915, uc_fw);
520 	}
521 
522 	intel_uc_fw_change_status(uc_fw, uc_fw->file_selected.path ? *uc_fw->file_selected.path ?
523 				  INTEL_UC_FIRMWARE_SELECTED :
524 				  INTEL_UC_FIRMWARE_DISABLED :
525 				  INTEL_UC_FIRMWARE_NOT_SUPPORTED);
526 }
527 
528 static void __force_fw_fetch_failures(struct intel_uc_fw *uc_fw, int e)
529 {
530 	struct drm_i915_private *i915 = __uc_fw_to_gt(uc_fw)->i915;
531 	bool user = e == -EINVAL;
532 
533 	if (i915_inject_probe_error(i915, e)) {
534 		/* non-existing blob */
535 		uc_fw->file_selected.path = "<invalid>";
536 		uc_fw->user_overridden = user;
537 	} else if (i915_inject_probe_error(i915, e)) {
538 		/* require next major version */
539 		uc_fw->file_wanted.ver.major += 1;
540 		uc_fw->file_wanted.ver.minor = 0;
541 		uc_fw->user_overridden = user;
542 	} else if (i915_inject_probe_error(i915, e)) {
543 		/* require next minor version */
544 		uc_fw->file_wanted.ver.minor += 1;
545 		uc_fw->user_overridden = user;
546 	} else if (uc_fw->file_wanted.ver.major &&
547 		   i915_inject_probe_error(i915, e)) {
548 		/* require prev major version */
549 		uc_fw->file_wanted.ver.major -= 1;
550 		uc_fw->file_wanted.ver.minor = 0;
551 		uc_fw->user_overridden = user;
552 	} else if (uc_fw->file_wanted.ver.minor &&
553 		   i915_inject_probe_error(i915, e)) {
554 		/* require prev minor version - hey, this should work! */
555 		uc_fw->file_wanted.ver.minor -= 1;
556 		uc_fw->user_overridden = user;
557 	} else if (user && i915_inject_probe_error(i915, e)) {
558 		/* officially unsupported platform */
559 		uc_fw->file_wanted.ver.major = 0;
560 		uc_fw->file_wanted.ver.minor = 0;
561 		uc_fw->user_overridden = true;
562 	}
563 }
564 
565 static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32 css_value)
566 {
567 	/* Get version numbers from the CSS header */
568 	ver->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css_value);
569 	ver->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css_value);
570 	ver->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css_value);
571 }
572 
573 static void guc_read_css_info(struct intel_uc_fw *uc_fw, struct uc_css_header *css)
574 {
575 	struct intel_guc *guc = container_of(uc_fw, struct intel_guc, fw);
576 
577 	/*
578 	 * The GuC firmware includes an extra version number to specify the
579 	 * submission API level. This allows submission code to work with
580 	 * multiple GuC versions without having to know the absolute firmware
581 	 * version number (there are likely to be multiple firmware releases
582 	 * which all support the same submission API level).
583 	 *
584 	 * Note that the spec for the CSS header defines this version number
585 	 * as 'vf_version' as it was originally intended for virtualisation.
586 	 * However, it is applicable to native submission as well.
587 	 *
588 	 * Unfortunately, due to an oversight, this version number was only
589 	 * exposed in the CSS header from v70.6.0.
590 	 */
591 	if (uc_fw->file_selected.ver.major >= 70) {
592 		if (uc_fw->file_selected.ver.minor >= 6) {
593 			/* v70.6.0 adds CSS header support */
594 			uc_unpack_css_version(&guc->submission_version, css->vf_version);
595 		} else if (uc_fw->file_selected.ver.minor >= 3) {
596 			/* v70.3.0 introduced v1.1.0 */
597 			guc->submission_version.major = 1;
598 			guc->submission_version.minor = 1;
599 			guc->submission_version.patch = 0;
600 		} else {
601 			/* v70.0.0 introduced v1.0.0 */
602 			guc->submission_version.major = 1;
603 			guc->submission_version.minor = 0;
604 			guc->submission_version.patch = 0;
605 		}
606 	} else if (uc_fw->file_selected.ver.major >= 69) {
607 		/* v69.0.0 introduced v0.10.0 */
608 		guc->submission_version.major = 0;
609 		guc->submission_version.minor = 10;
610 		guc->submission_version.patch = 0;
611 	} else {
612 		/* Prior versions were v0.1.0 */
613 		guc->submission_version.major = 0;
614 		guc->submission_version.minor = 1;
615 		guc->submission_version.patch = 0;
616 	}
617 
618 	uc_fw->private_data_size = css->private_data_size;
619 }
620 
621 static int __check_ccs_header(struct intel_gt *gt,
622 			      const void *fw_data, size_t fw_size,
623 			      struct intel_uc_fw *uc_fw)
624 {
625 	struct uc_css_header *css;
626 	size_t size;
627 
628 	/* Check the size of the blob before examining buffer contents */
629 	if (unlikely(fw_size < sizeof(struct uc_css_header))) {
630 		gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
631 			intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
632 			fw_size, sizeof(struct uc_css_header));
633 		return -ENODATA;
634 	}
635 
636 	css = (struct uc_css_header *)fw_data;
637 
638 	/* Check integrity of size values inside CSS header */
639 	size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw -
640 		css->exponent_size_dw) * sizeof(u32);
641 	if (unlikely(size != sizeof(struct uc_css_header))) {
642 		gt_warn(gt, "%s firmware %s: unexpected header size: %zu != %zu\n",
643 			intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
644 			fw_size, sizeof(struct uc_css_header));
645 		return -EPROTO;
646 	}
647 
648 	/* uCode size must calculated from other sizes */
649 	uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
650 
651 	/* now RSA */
652 	uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
653 
654 	/* At least, it should have header, uCode and RSA. Size of all three. */
655 	size = sizeof(struct uc_css_header) + uc_fw->ucode_size + uc_fw->rsa_size;
656 	if (unlikely(fw_size < size)) {
657 		gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
658 			intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
659 			fw_size, size);
660 		return -ENOEXEC;
661 	}
662 
663 	/* Sanity check whether this fw is not larger than whole WOPCM memory */
664 	size = __intel_uc_fw_get_upload_size(uc_fw);
665 	if (unlikely(size >= gt->wopcm.size)) {
666 		gt_warn(gt, "%s firmware %s: invalid size: %zu > %zu\n",
667 			intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
668 			size, (size_t)gt->wopcm.size);
669 		return -E2BIG;
670 	}
671 
672 	uc_unpack_css_version(&uc_fw->file_selected.ver, css->sw_version);
673 
674 	if (uc_fw->type == INTEL_UC_FW_TYPE_GUC)
675 		guc_read_css_info(uc_fw, css);
676 
677 	return 0;
678 }
679 
680 static int check_gsc_manifest(struct intel_gt *gt,
681 			      const struct firmware *fw,
682 			      struct intel_uc_fw *uc_fw)
683 {
684 	switch (uc_fw->type) {
685 	case INTEL_UC_FW_TYPE_HUC:
686 		intel_huc_fw_get_binary_info(uc_fw, fw->data, fw->size);
687 		break;
688 	case INTEL_UC_FW_TYPE_GSC:
689 		intel_gsc_fw_get_binary_info(uc_fw, fw->data, fw->size);
690 		break;
691 	default:
692 		MISSING_CASE(uc_fw->type);
693 		return -EINVAL;
694 	}
695 
696 	if (uc_fw->dma_start_offset) {
697 		u32 delta = uc_fw->dma_start_offset;
698 
699 		__check_ccs_header(gt, fw->data + delta, fw->size - delta, uc_fw);
700 	}
701 
702 	return 0;
703 }
704 
705 static int check_ccs_header(struct intel_gt *gt,
706 			    const struct firmware *fw,
707 			    struct intel_uc_fw *uc_fw)
708 {
709 	return __check_ccs_header(gt, fw->data, fw->size, uc_fw);
710 }
711 
712 static bool is_ver_8bit(struct intel_uc_fw_ver *ver)
713 {
714 	return ver->major < 0xFF && ver->minor < 0xFF && ver->patch < 0xFF;
715 }
716 
717 static int guc_check_version_range(struct intel_uc_fw *uc_fw)
718 {
719 	struct intel_guc *guc = container_of(uc_fw, struct intel_guc, fw);
720 	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
721 
722 	/*
723 	 * GuC version number components are defined as being 8-bits.
724 	 * The submission code relies on this to optimise version comparison
725 	 * tests. So enforce the restriction here.
726 	 */
727 
728 	if (!is_ver_8bit(&uc_fw->file_selected.ver)) {
729 		gt_warn(gt, "%s firmware: invalid file version: 0x%02X:%02X:%02X\n",
730 			intel_uc_fw_type_repr(uc_fw->type),
731 			uc_fw->file_selected.ver.major,
732 			uc_fw->file_selected.ver.minor,
733 			uc_fw->file_selected.ver.patch);
734 		return -EINVAL;
735 	}
736 
737 	if (!is_ver_8bit(&guc->submission_version)) {
738 		gt_warn(gt, "%s firmware: invalid submit version: 0x%02X:%02X:%02X\n",
739 			intel_uc_fw_type_repr(uc_fw->type),
740 			guc->submission_version.major,
741 			guc->submission_version.minor,
742 			guc->submission_version.patch);
743 		return -EINVAL;
744 	}
745 
746 	return i915_inject_probe_error(gt->i915, -EINVAL);
747 }
748 
749 static int check_fw_header(struct intel_gt *gt,
750 			   const struct firmware *fw,
751 			   struct intel_uc_fw *uc_fw)
752 {
753 	int err = 0;
754 
755 	if (uc_fw->has_gsc_headers)
756 		err = check_gsc_manifest(gt, fw, uc_fw);
757 	else
758 		err = check_ccs_header(gt, fw, uc_fw);
759 	if (err)
760 		return err;
761 
762 	return 0;
763 }
764 
765 static int try_firmware_load(struct intel_uc_fw *uc_fw, const struct firmware **fw)
766 {
767 	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
768 	struct device *dev = gt->i915->drm.dev;
769 	int err;
770 
771 	err = firmware_request_nowarn(fw, uc_fw->file_selected.path, dev);
772 
773 	if (err)
774 		return err;
775 
776 	if (uc_fw->needs_ggtt_mapping && (*fw)->size > INTEL_UC_RSVD_GGTT_PER_FW) {
777 		gt_err(gt, "%s firmware %s: size (%zuKB) exceeds max supported size (%uKB)\n",
778 		       intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
779 		       (*fw)->size / SZ_1K, INTEL_UC_RSVD_GGTT_PER_FW / SZ_1K);
780 
781 		/* try to find another blob to load */
782 		release_firmware(*fw);
783 		*fw = NULL;
784 		return -ENOENT;
785 	}
786 
787 	return 0;
788 }
789 
790 static int check_mtl_huc_guc_compatibility(struct intel_gt *gt,
791 					   struct intel_uc_fw_file *huc_selected)
792 {
793 	struct intel_uc_fw_file *guc_selected = &gt->uc.guc.fw.file_selected;
794 	struct intel_uc_fw_ver *huc_ver = &huc_selected->ver;
795 	struct intel_uc_fw_ver *guc_ver = &guc_selected->ver;
796 	bool new_huc, new_guc;
797 
798 	/* we can only do this check after having fetched both GuC and HuC */
799 	GEM_BUG_ON(!huc_selected->path || !guc_selected->path);
800 
801 	/*
802 	 * Due to changes in the authentication flow for MTL, HuC 8.5.1 or newer
803 	 * requires GuC 70.7.0 or newer. Older HuC binaries will instead require
804 	 * GuC < 70.7.0.
805 	 */
806 	new_huc = huc_ver->major > 8 ||
807 		  (huc_ver->major == 8 && huc_ver->minor > 5) ||
808 		  (huc_ver->major == 8 && huc_ver->minor == 5 && huc_ver->patch >= 1);
809 
810 	new_guc = guc_ver->major > 70 ||
811 		  (guc_ver->major == 70 && guc_ver->minor >= 7);
812 
813 	if (new_huc != new_guc) {
814 		UNEXPECTED(gt, "HuC %u.%u.%u is incompatible with GuC %u.%u.%u\n",
815 			   huc_ver->major, huc_ver->minor, huc_ver->patch,
816 			   guc_ver->major, guc_ver->minor, guc_ver->patch);
817 		gt_info(gt, "MTL GuC 70.7.0+ and HuC 8.5.1+ don't work with older releases\n");
818 		return -ENOEXEC;
819 	}
820 
821 	return 0;
822 }
823 
824 int intel_uc_check_file_version(struct intel_uc_fw *uc_fw, bool *old_ver)
825 {
826 	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
827 	struct intel_uc_fw_file *wanted = &uc_fw->file_wanted;
828 	struct intel_uc_fw_file *selected = &uc_fw->file_selected;
829 	int ret;
830 
831 	/*
832 	 * MTL has some compatibility issues with early GuC/HuC binaries
833 	 * not working with newer ones. This is specific to MTL and we
834 	 * don't expect it to extend to other platforms.
835 	 */
836 	if (IS_METEORLAKE(gt->i915) && uc_fw->type == INTEL_UC_FW_TYPE_HUC) {
837 		ret = check_mtl_huc_guc_compatibility(gt, selected);
838 		if (ret)
839 			return ret;
840 	}
841 
842 	if (!wanted->ver.major || !selected->ver.major)
843 		return 0;
844 
845 	/* Check the file's major version was as it claimed */
846 	if (selected->ver.major != wanted->ver.major) {
847 		UNEXPECTED(gt, "%s firmware %s: unexpected version: %u.%u != %u.%u\n",
848 			   intel_uc_fw_type_repr(uc_fw->type), selected->path,
849 			   selected->ver.major, selected->ver.minor,
850 			   wanted->ver.major, wanted->ver.minor);
851 		if (!intel_uc_fw_is_overridden(uc_fw))
852 			return -ENOEXEC;
853 	} else if (old_ver) {
854 		if (selected->ver.minor < wanted->ver.minor)
855 			*old_ver = true;
856 		else if ((selected->ver.minor == wanted->ver.minor) &&
857 			 (selected->ver.patch < wanted->ver.patch))
858 			*old_ver = true;
859 	}
860 
861 	return 0;
862 }
863 
864 /**
865  * intel_uc_fw_fetch - fetch uC firmware
866  * @uc_fw: uC firmware
867  *
868  * Fetch uC firmware into GEM obj.
869  *
870  * Return: 0 on success, a negative errno code on failure.
871  */
872 int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
873 {
874 	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
875 	struct drm_i915_private *i915 = gt->i915;
876 	struct intel_uc_fw_file file_ideal;
877 	struct drm_i915_gem_object *obj;
878 	const struct firmware *fw = NULL;
879 	bool old_ver = false;
880 	int err;
881 
882 	GEM_BUG_ON(!gt->wopcm.size);
883 	GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw));
884 
885 	err = i915_inject_probe_error(i915, -ENXIO);
886 	if (err)
887 		goto fail;
888 
889 	__force_fw_fetch_failures(uc_fw, -EINVAL);
890 	__force_fw_fetch_failures(uc_fw, -ESTALE);
891 
892 	err = try_firmware_load(uc_fw, &fw);
893 	memcpy(&file_ideal, &uc_fw->file_wanted, sizeof(file_ideal));
894 
895 	/* Any error is terminal if overriding. Don't bother searching for older versions */
896 	if (err && intel_uc_fw_is_overridden(uc_fw))
897 		goto fail;
898 
899 	while (err == -ENOENT) {
900 		old_ver = true;
901 
902 		__uc_fw_auto_select(i915, uc_fw);
903 		if (!uc_fw->file_selected.path) {
904 			/*
905 			 * No more options! But set the path back to something
906 			 * valid just in case it gets dereferenced.
907 			 */
908 			uc_fw->file_selected.path = file_ideal.path;
909 
910 			/* Also, preserve the version that was really wanted */
911 			memcpy(&uc_fw->file_wanted, &file_ideal, sizeof(uc_fw->file_wanted));
912 			break;
913 		}
914 
915 		err = try_firmware_load(uc_fw, &fw);
916 	}
917 
918 	if (err)
919 		goto fail;
920 
921 	err = check_fw_header(gt, fw, uc_fw);
922 	if (err)
923 		goto fail;
924 
925 	if (uc_fw->type == INTEL_UC_FW_TYPE_GUC) {
926 		err = guc_check_version_range(uc_fw);
927 		if (err)
928 			goto fail;
929 	}
930 
931 	err = intel_uc_check_file_version(uc_fw, &old_ver);
932 	if (err)
933 		goto fail;
934 
935 	if (old_ver && uc_fw->file_selected.ver.major) {
936 		/* Preserve the version that was really wanted */
937 		memcpy(&uc_fw->file_wanted, &file_ideal, sizeof(uc_fw->file_wanted));
938 
939 		UNEXPECTED(gt, "%s firmware %s (%d.%d.%d) is recommended, but only %s (%d.%d.%d) was found\n",
940 			   intel_uc_fw_type_repr(uc_fw->type),
941 			   uc_fw->file_wanted.path,
942 			   uc_fw->file_wanted.ver.major,
943 			   uc_fw->file_wanted.ver.minor,
944 			   uc_fw->file_wanted.ver.patch,
945 			   uc_fw->file_selected.path,
946 			   uc_fw->file_selected.ver.major,
947 			   uc_fw->file_selected.ver.minor,
948 			   uc_fw->file_selected.ver.patch);
949 		gt_info(gt, "Consider updating your linux-firmware pkg or downloading from %s\n",
950 			INTEL_UC_FIRMWARE_URL);
951 	}
952 
953 	if (HAS_LMEM(i915)) {
954 		obj = i915_gem_object_create_lmem_from_data(i915, fw->data, fw->size);
955 		if (!IS_ERR(obj))
956 			obj->flags |= I915_BO_ALLOC_PM_EARLY;
957 	} else {
958 		obj = i915_gem_object_create_shmem_from_data(i915, fw->data, fw->size);
959 	}
960 
961 	if (IS_ERR(obj)) {
962 		err = PTR_ERR(obj);
963 		goto fail;
964 	}
965 
966 	uc_fw->obj = obj;
967 	uc_fw->size = fw->size;
968 	intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE);
969 
970 	release_firmware(fw);
971 	return 0;
972 
973 fail:
974 	intel_uc_fw_change_status(uc_fw, err == -ENOENT ?
975 				  INTEL_UC_FIRMWARE_MISSING :
976 				  INTEL_UC_FIRMWARE_ERROR);
977 
978 	gt_probe_error(gt, "%s firmware %s: fetch failed %pe\n",
979 		       intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, ERR_PTR(err));
980 	gt_info(gt, "%s firmware(s) can be downloaded from %s\n",
981 		intel_uc_fw_type_repr(uc_fw->type), INTEL_UC_FIRMWARE_URL);
982 
983 	release_firmware(fw);		/* OK even if fw is NULL */
984 	return err;
985 }
986 
987 static u32 uc_fw_ggtt_offset(struct intel_uc_fw *uc_fw)
988 {
989 	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
990 	struct i915_ggtt *ggtt = gt->ggtt;
991 	struct drm_mm_node *node = &ggtt->uc_fw;
992 	u32 offset = uc_fw->type * INTEL_UC_RSVD_GGTT_PER_FW;
993 
994 	/*
995 	 * The media GT shares the GGTT with the root GT, which means that
996 	 * we need to use different offsets for the binaries on the media GT.
997 	 * To keep the math simple, we use 8MB for the root tile and 8MB for
998 	 * the media one. This will need to be updated if we ever have more
999 	 * than 1 media GT.
1000 	 */
1001 	BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > SZ_8M);
1002 	GEM_BUG_ON(gt->type == GT_MEDIA && gt->info.id > 1);
1003 	if (gt->type == GT_MEDIA)
1004 		offset += SZ_8M;
1005 
1006 	GEM_BUG_ON(!drm_mm_node_allocated(node));
1007 	GEM_BUG_ON(upper_32_bits(node->start));
1008 	GEM_BUG_ON(upper_32_bits(node->start + node->size - 1));
1009 	GEM_BUG_ON(offset + uc_fw->obj->base.size > node->size);
1010 	GEM_BUG_ON(uc_fw->obj->base.size > INTEL_UC_RSVD_GGTT_PER_FW);
1011 
1012 	return lower_32_bits(node->start + offset);
1013 }
1014 
1015 static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
1016 {
1017 	struct drm_i915_gem_object *obj = uc_fw->obj;
1018 	struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
1019 	struct i915_vma_resource *vma_res = &uc_fw->vma_res;
1020 	u32 pte_flags = 0;
1021 
1022 	if (!uc_fw->needs_ggtt_mapping)
1023 		return;
1024 
1025 	vma_res->start = uc_fw_ggtt_offset(uc_fw);
1026 	vma_res->node_size = obj->base.size;
1027 	vma_res->bi.pages = obj->mm.pages;
1028 
1029 	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
1030 
1031 	/* uc_fw->obj cache domains were not controlled across suspend */
1032 	if (i915_gem_object_has_struct_page(obj))
1033 		drm_clflush_sg(vma_res->bi.pages);
1034 
1035 	if (i915_gem_object_is_lmem(obj))
1036 		pte_flags |= PTE_LM;
1037 
1038 	if (ggtt->vm.raw_insert_entries)
1039 		ggtt->vm.raw_insert_entries(&ggtt->vm, vma_res,
1040 					    i915_gem_get_pat_index(ggtt->vm.i915,
1041 								   I915_CACHE_NONE),
1042 					    pte_flags);
1043 	else
1044 		ggtt->vm.insert_entries(&ggtt->vm, vma_res,
1045 					i915_gem_get_pat_index(ggtt->vm.i915,
1046 							       I915_CACHE_NONE),
1047 					pte_flags);
1048 }
1049 
1050 static void uc_fw_unbind_ggtt(struct intel_uc_fw *uc_fw)
1051 {
1052 	struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
1053 	struct i915_vma_resource *vma_res = &uc_fw->vma_res;
1054 
1055 	if (!vma_res->node_size)
1056 		return;
1057 
1058 	ggtt->vm.clear_range(&ggtt->vm, vma_res->start, vma_res->node_size);
1059 }
1060 
1061 static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
1062 {
1063 	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
1064 	struct intel_uncore *uncore = gt->uncore;
1065 	u64 offset;
1066 	int ret;
1067 
1068 	ret = i915_inject_probe_error(gt->i915, -ETIMEDOUT);
1069 	if (ret)
1070 		return ret;
1071 
1072 	intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
1073 
1074 	/* Set the source address for the uCode */
1075 	offset = uc_fw->vma_res.start + uc_fw->dma_start_offset;
1076 	GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000);
1077 	intel_uncore_write_fw(uncore, DMA_ADDR_0_LOW, lower_32_bits(offset));
1078 	intel_uncore_write_fw(uncore, DMA_ADDR_0_HIGH, upper_32_bits(offset));
1079 
1080 	/* Set the DMA destination */
1081 	intel_uncore_write_fw(uncore, DMA_ADDR_1_LOW, dst_offset);
1082 	intel_uncore_write_fw(uncore, DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
1083 
1084 	/*
1085 	 * Set the transfer size. The header plus uCode will be copied to WOPCM
1086 	 * via DMA, excluding any other components
1087 	 */
1088 	intel_uncore_write_fw(uncore, DMA_COPY_SIZE,
1089 			      sizeof(struct uc_css_header) + uc_fw->ucode_size);
1090 
1091 	/* Start the DMA */
1092 	intel_uncore_write_fw(uncore, DMA_CTRL,
1093 			      _MASKED_BIT_ENABLE(dma_flags | START_DMA));
1094 
1095 	/* Wait for DMA to finish */
1096 	ret = intel_wait_for_register_fw(uncore, DMA_CTRL, START_DMA, 0, 100);
1097 	if (ret)
1098 		gt_err(gt, "DMA for %s fw failed, DMA_CTRL=%u\n",
1099 		       intel_uc_fw_type_repr(uc_fw->type),
1100 		       intel_uncore_read_fw(uncore, DMA_CTRL));
1101 
1102 	/* Disable the bits once DMA is over */
1103 	intel_uncore_write_fw(uncore, DMA_CTRL, _MASKED_BIT_DISABLE(dma_flags));
1104 
1105 	intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
1106 
1107 	return ret;
1108 }
1109 
1110 int intel_uc_fw_mark_load_failed(struct intel_uc_fw *uc_fw, int err)
1111 {
1112 	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
1113 
1114 	GEM_BUG_ON(!intel_uc_fw_is_loadable(uc_fw));
1115 
1116 	gt_probe_error(gt, "Failed to load %s firmware %s %pe\n",
1117 		       intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, ERR_PTR(err));
1118 	intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_LOAD_FAIL);
1119 
1120 	return err;
1121 }
1122 
1123 /**
1124  * intel_uc_fw_upload - load uC firmware using custom loader
1125  * @uc_fw: uC firmware
1126  * @dst_offset: destination offset
1127  * @dma_flags: flags for flags for dma ctrl
1128  *
1129  * Loads uC firmware and updates internal flags.
1130  *
1131  * Return: 0 on success, non-zero on failure.
1132  */
1133 int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
1134 {
1135 	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
1136 	int err;
1137 
1138 	/* make sure the status was cleared the last time we reset the uc */
1139 	GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw));
1140 
1141 	err = i915_inject_probe_error(gt->i915, -ENOEXEC);
1142 	if (err)
1143 		return err;
1144 
1145 	if (!intel_uc_fw_is_loadable(uc_fw))
1146 		return -ENOEXEC;
1147 
1148 	/* Call custom loader */
1149 	err = uc_fw_xfer(uc_fw, dst_offset, dma_flags);
1150 	if (err)
1151 		goto fail;
1152 
1153 	intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_TRANSFERRED);
1154 	return 0;
1155 
1156 fail:
1157 	return intel_uc_fw_mark_load_failed(uc_fw, err);
1158 }
1159 
1160 static inline bool uc_fw_need_rsa_in_memory(struct intel_uc_fw *uc_fw)
1161 {
1162 	/*
1163 	 * The HW reads the GuC RSA from memory if the key size is > 256 bytes,
1164 	 * while it reads it from the 64 RSA registers if it is smaller.
1165 	 * The HuC RSA is always read from memory.
1166 	 */
1167 	return uc_fw->type == INTEL_UC_FW_TYPE_HUC || uc_fw->rsa_size > 256;
1168 }
1169 
1170 static int uc_fw_rsa_data_create(struct intel_uc_fw *uc_fw)
1171 {
1172 	struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
1173 	struct i915_vma *vma;
1174 	size_t copied;
1175 	void *vaddr;
1176 	int err;
1177 
1178 	err = i915_inject_probe_error(gt->i915, -ENXIO);
1179 	if (err)
1180 		return err;
1181 
1182 	if (!uc_fw_need_rsa_in_memory(uc_fw))
1183 		return 0;
1184 
1185 	/*
1186 	 * uC firmwares will sit above GUC_GGTT_TOP and will not map through
1187 	 * GGTT. Unfortunately, this means that the GuC HW cannot perform the uC
1188 	 * authentication from memory, as the RSA offset now falls within the
1189 	 * GuC inaccessible range. We resort to perma-pinning an additional vma
1190 	 * within the accessible range that only contains the RSA signature.
1191 	 * The GuC HW can use this extra pinning to perform the authentication
1192 	 * since its GGTT offset will be GuC accessible.
1193 	 */
1194 	GEM_BUG_ON(uc_fw->rsa_size > PAGE_SIZE);
1195 	vma = intel_guc_allocate_vma(&gt->uc.guc, PAGE_SIZE);
1196 	if (IS_ERR(vma))
1197 		return PTR_ERR(vma);
1198 
1199 	vaddr = i915_gem_object_pin_map_unlocked(vma->obj,
1200 						 i915_coherent_map_type(gt->i915, vma->obj, true));
1201 	if (IS_ERR(vaddr)) {
1202 		i915_vma_unpin_and_release(&vma, 0);
1203 		err = PTR_ERR(vaddr);
1204 		goto unpin_out;
1205 	}
1206 
1207 	copied = intel_uc_fw_copy_rsa(uc_fw, vaddr, vma->size);
1208 	i915_gem_object_unpin_map(vma->obj);
1209 
1210 	if (copied < uc_fw->rsa_size) {
1211 		err = -ENOMEM;
1212 		goto unpin_out;
1213 	}
1214 
1215 	uc_fw->rsa_data = vma;
1216 
1217 	return 0;
1218 
1219 unpin_out:
1220 	i915_vma_unpin_and_release(&vma, 0);
1221 	return err;
1222 }
1223 
1224 static void uc_fw_rsa_data_destroy(struct intel_uc_fw *uc_fw)
1225 {
1226 	i915_vma_unpin_and_release(&uc_fw->rsa_data, 0);
1227 }
1228 
1229 int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
1230 {
1231 	int err;
1232 
1233 	/* this should happen before the load! */
1234 	GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw));
1235 
1236 	if (!intel_uc_fw_is_available(uc_fw))
1237 		return -ENOEXEC;
1238 
1239 	err = i915_gem_object_pin_pages_unlocked(uc_fw->obj);
1240 	if (err) {
1241 		gt_dbg(__uc_fw_to_gt(uc_fw), "%s fw pin-pages failed %pe\n",
1242 		       intel_uc_fw_type_repr(uc_fw->type), ERR_PTR(err));
1243 		goto out;
1244 	}
1245 
1246 	err = uc_fw_rsa_data_create(uc_fw);
1247 	if (err) {
1248 		gt_dbg(__uc_fw_to_gt(uc_fw), "%s fw rsa data creation failed %pe\n",
1249 		       intel_uc_fw_type_repr(uc_fw->type), ERR_PTR(err));
1250 		goto out_unpin;
1251 	}
1252 
1253 	uc_fw_bind_ggtt(uc_fw);
1254 
1255 	return 0;
1256 
1257 out_unpin:
1258 	i915_gem_object_unpin_pages(uc_fw->obj);
1259 out:
1260 	return err;
1261 }
1262 
1263 void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
1264 {
1265 	uc_fw_unbind_ggtt(uc_fw);
1266 	uc_fw_rsa_data_destroy(uc_fw);
1267 
1268 	if (i915_gem_object_has_pinned_pages(uc_fw->obj))
1269 		i915_gem_object_unpin_pages(uc_fw->obj);
1270 
1271 	intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE);
1272 }
1273 
1274 void intel_uc_fw_resume_mapping(struct intel_uc_fw *uc_fw)
1275 {
1276 	if (!intel_uc_fw_is_available(uc_fw))
1277 		return;
1278 
1279 	if (!i915_gem_object_has_pinned_pages(uc_fw->obj))
1280 		return;
1281 
1282 	uc_fw_bind_ggtt(uc_fw);
1283 }
1284 
1285 /**
1286  * intel_uc_fw_cleanup_fetch - cleanup uC firmware
1287  * @uc_fw: uC firmware
1288  *
1289  * Cleans up uC firmware by releasing the firmware GEM obj.
1290  */
1291 void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw)
1292 {
1293 	if (!intel_uc_fw_is_available(uc_fw))
1294 		return;
1295 
1296 	i915_gem_object_put(fetch_and_zero(&uc_fw->obj));
1297 
1298 	intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_SELECTED);
1299 }
1300 
1301 /**
1302  * intel_uc_fw_copy_rsa - copy fw RSA to buffer
1303  *
1304  * @uc_fw: uC firmware
1305  * @dst: dst buffer
1306  * @max_len: max number of bytes to copy
1307  *
1308  * Return: number of copied bytes.
1309  */
1310 size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len)
1311 {
1312 	struct intel_memory_region *mr = uc_fw->obj->mm.region;
1313 	u32 size = min_t(u32, uc_fw->rsa_size, max_len);
1314 	u32 offset = uc_fw->dma_start_offset + sizeof(struct uc_css_header) + uc_fw->ucode_size;
1315 	struct sgt_iter iter;
1316 	size_t count = 0;
1317 	int idx;
1318 
1319 	/* Called during reset handling, must be atomic [no fs_reclaim] */
1320 	GEM_BUG_ON(!intel_uc_fw_is_available(uc_fw));
1321 
1322 	idx = offset >> PAGE_SHIFT;
1323 	offset = offset_in_page(offset);
1324 	if (i915_gem_object_has_struct_page(uc_fw->obj)) {
1325 		struct page *page;
1326 
1327 		for_each_sgt_page(page, iter, uc_fw->obj->mm.pages) {
1328 			u32 len = min_t(u32, size, PAGE_SIZE - offset);
1329 			void *vaddr;
1330 
1331 			if (idx > 0) {
1332 				idx--;
1333 				continue;
1334 			}
1335 
1336 			vaddr = kmap_atomic(page);
1337 			memcpy(dst, vaddr + offset, len);
1338 			kunmap_atomic(vaddr);
1339 
1340 			offset = 0;
1341 			dst += len;
1342 			size -= len;
1343 			count += len;
1344 			if (!size)
1345 				break;
1346 		}
1347 	} else {
1348 		dma_addr_t addr;
1349 
1350 		for_each_sgt_daddr(addr, iter, uc_fw->obj->mm.pages) {
1351 			u32 len = min_t(u32, size, PAGE_SIZE - offset);
1352 			void __iomem *vaddr;
1353 
1354 			if (idx > 0) {
1355 				idx--;
1356 				continue;
1357 			}
1358 
1359 			vaddr = io_mapping_map_atomic_wc(&mr->iomap,
1360 							 addr - mr->region.start);
1361 			memcpy_fromio(dst, vaddr + offset, len);
1362 			io_mapping_unmap_atomic(vaddr);
1363 
1364 			offset = 0;
1365 			dst += len;
1366 			size -= len;
1367 			count += len;
1368 			if (!size)
1369 				break;
1370 		}
1371 	}
1372 
1373 	return count;
1374 }
1375 
1376 /**
1377  * intel_uc_fw_dump - dump information about uC firmware
1378  * @uc_fw: uC firmware
1379  * @p: the &drm_printer
1380  *
1381  * Pretty printer for uC firmware.
1382  */
1383 void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p)
1384 {
1385 	bool got_wanted;
1386 
1387 	drm_printf(p, "%s firmware: %s\n",
1388 		   intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path);
1389 	if (uc_fw->file_selected.path != uc_fw->file_wanted.path)
1390 		drm_printf(p, "%s firmware wanted: %s\n",
1391 			   intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_wanted.path);
1392 	drm_printf(p, "\tstatus: %s\n",
1393 		   intel_uc_fw_status_repr(uc_fw->status));
1394 
1395 	if (uc_fw->file_selected.ver.major < uc_fw->file_wanted.ver.major)
1396 		got_wanted = false;
1397 	else if ((uc_fw->file_selected.ver.major == uc_fw->file_wanted.ver.major) &&
1398 		 (uc_fw->file_selected.ver.minor < uc_fw->file_wanted.ver.minor))
1399 		got_wanted = false;
1400 	else if ((uc_fw->file_selected.ver.major == uc_fw->file_wanted.ver.major) &&
1401 		 (uc_fw->file_selected.ver.minor == uc_fw->file_wanted.ver.minor) &&
1402 		 (uc_fw->file_selected.ver.patch < uc_fw->file_wanted.ver.patch))
1403 		got_wanted = false;
1404 	else
1405 		got_wanted = true;
1406 
1407 	if (!got_wanted)
1408 		drm_printf(p, "\tversion: wanted %u.%u.%u, found %u.%u.%u\n",
1409 			   uc_fw->file_wanted.ver.major,
1410 			   uc_fw->file_wanted.ver.minor,
1411 			   uc_fw->file_wanted.ver.patch,
1412 			   uc_fw->file_selected.ver.major,
1413 			   uc_fw->file_selected.ver.minor,
1414 			   uc_fw->file_selected.ver.patch);
1415 	else
1416 		drm_printf(p, "\tversion: found %u.%u.%u\n",
1417 			   uc_fw->file_selected.ver.major,
1418 			   uc_fw->file_selected.ver.minor,
1419 			   uc_fw->file_selected.ver.patch);
1420 	drm_printf(p, "\tuCode: %u bytes\n", uc_fw->ucode_size);
1421 	drm_printf(p, "\tRSA: %u bytes\n", uc_fw->rsa_size);
1422 }
1423