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