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