1
2
3
4
5
6#include <linux/bitfield.h>
7#include <linux/firmware.h>
8#include <drm/drm_print.h>
9
10#include "intel_uc_fw.h"
11#include "intel_uc_fw_abi.h"
12#include "i915_drv.h"
13
14static inline struct intel_gt *
15____uc_fw_to_gt(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type)
16{
17 if (type == INTEL_UC_FW_TYPE_GUC)
18 return container_of(uc_fw, struct intel_gt, uc.guc.fw);
19
20 GEM_BUG_ON(type != INTEL_UC_FW_TYPE_HUC);
21 return container_of(uc_fw, struct intel_gt, uc.huc.fw);
22}
23
24static inline struct intel_gt *__uc_fw_to_gt(struct intel_uc_fw *uc_fw)
25{
26 GEM_BUG_ON(uc_fw->status == INTEL_UC_FIRMWARE_UNINITIALIZED);
27 return ____uc_fw_to_gt(uc_fw, uc_fw->type);
28}
29
30#ifdef CONFIG_DRM_I915_DEBUG_GUC
31void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
32 enum intel_uc_fw_status status)
33{
34 uc_fw->__status = status;
35 drm_dbg(&__uc_fw_to_gt(uc_fw)->i915->drm,
36 "%s firmware -> %s\n",
37 intel_uc_fw_type_repr(uc_fw->type),
38 status == INTEL_UC_FIRMWARE_SELECTED ?
39 uc_fw->path : intel_uc_fw_status_repr(status));
40}
41#endif
42
43
44
45
46
47
48
49
50#define INTEL_UC_FIRMWARE_DEFS(fw_def, guc_def, huc_def) \
51 fw_def(ALDERLAKE_S, 0, guc_def(tgl, 49, 0, 1), huc_def(tgl, 7, 5, 0)) \
52 fw_def(ROCKETLAKE, 0, guc_def(tgl, 49, 0, 1), huc_def(tgl, 7, 5, 0)) \
53 fw_def(TIGERLAKE, 0, guc_def(tgl, 49, 0, 1), huc_def(tgl, 7, 5, 0)) \
54 fw_def(JASPERLAKE, 0, guc_def(ehl, 49, 0, 1), huc_def(ehl, 9, 0, 0)) \
55 fw_def(ELKHARTLAKE, 0, guc_def(ehl, 49, 0, 1), huc_def(ehl, 9, 0, 0)) \
56 fw_def(ICELAKE, 0, guc_def(icl, 49, 0, 1), huc_def(icl, 9, 0, 0)) \
57 fw_def(COMETLAKE, 5, guc_def(cml, 49, 0, 1), huc_def(cml, 4, 0, 0)) \
58 fw_def(COMETLAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \
59 fw_def(COFFEELAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \
60 fw_def(GEMINILAKE, 0, guc_def(glk, 49, 0, 1), huc_def(glk, 4, 0, 0)) \
61 fw_def(KABYLAKE, 0, guc_def(kbl, 49, 0, 1), huc_def(kbl, 4, 0, 0)) \
62 fw_def(BROXTON, 0, guc_def(bxt, 49, 0, 1), huc_def(bxt, 2, 0, 0)) \
63 fw_def(SKYLAKE, 0, guc_def(skl, 49, 0, 1), huc_def(skl, 2, 0, 0))
64
65#define __MAKE_UC_FW_PATH(prefix_, name_, major_, minor_, patch_) \
66 "i915/" \
67 __stringify(prefix_) name_ \
68 __stringify(major_) "." \
69 __stringify(minor_) "." \
70 __stringify(patch_) ".bin"
71
72#define MAKE_GUC_FW_PATH(prefix_, major_, minor_, patch_) \
73 __MAKE_UC_FW_PATH(prefix_, "_guc_", major_, minor_, patch_)
74
75#define MAKE_HUC_FW_PATH(prefix_, major_, minor_, bld_num_) \
76 __MAKE_UC_FW_PATH(prefix_, "_huc_", major_, minor_, bld_num_)
77
78
79#define INTEL_UC_MODULE_FW(platform_, revid_, guc_, huc_) \
80 MODULE_FIRMWARE(guc_); \
81 MODULE_FIRMWARE(huc_);
82
83INTEL_UC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH, MAKE_HUC_FW_PATH)
84
85
86struct __packed uc_fw_blob {
87 u8 major;
88 u8 minor;
89 const char *path;
90};
91
92#define UC_FW_BLOB(major_, minor_, path_) \
93 { .major = major_, .minor = minor_, .path = path_ }
94
95#define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
96 UC_FW_BLOB(major_, minor_, \
97 MAKE_GUC_FW_PATH(prefix_, major_, minor_, patch_))
98
99#define HUC_FW_BLOB(prefix_, major_, minor_, bld_num_) \
100 UC_FW_BLOB(major_, minor_, \
101 MAKE_HUC_FW_PATH(prefix_, major_, minor_, bld_num_))
102
103struct __packed uc_fw_platform_requirement {
104 enum intel_platform p;
105 u8 rev;
106 const struct uc_fw_blob blobs[INTEL_UC_FW_NUM_TYPES];
107};
108
109#define MAKE_FW_LIST(platform_, revid_, guc_, huc_) \
110{ \
111 .p = INTEL_##platform_, \
112 .rev = revid_, \
113 .blobs[INTEL_UC_FW_TYPE_GUC] = guc_, \
114 .blobs[INTEL_UC_FW_TYPE_HUC] = huc_, \
115},
116
117static void
118__uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
119{
120 static const struct uc_fw_platform_requirement fw_blobs[] = {
121 INTEL_UC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, HUC_FW_BLOB)
122 };
123 enum intel_platform p = INTEL_INFO(i915)->platform;
124 u8 rev = INTEL_REVID(i915);
125 int i;
126
127 for (i = 0; i < ARRAY_SIZE(fw_blobs) && p <= fw_blobs[i].p; i++) {
128 if (p == fw_blobs[i].p && rev >= fw_blobs[i].rev) {
129 const struct uc_fw_blob *blob =
130 &fw_blobs[i].blobs[uc_fw->type];
131 uc_fw->path = blob->path;
132 uc_fw->major_ver_wanted = blob->major;
133 uc_fw->minor_ver_wanted = blob->minor;
134 break;
135 }
136 }
137
138
139 if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST)) {
140 for (i = 1; i < ARRAY_SIZE(fw_blobs); i++) {
141 if (fw_blobs[i].p < fw_blobs[i - 1].p)
142 continue;
143
144 if (fw_blobs[i].p == fw_blobs[i - 1].p &&
145 fw_blobs[i].rev < fw_blobs[i - 1].rev)
146 continue;
147
148 pr_err("invalid FW blob order: %s r%u comes before %s r%u\n",
149 intel_platform_name(fw_blobs[i - 1].p),
150 fw_blobs[i - 1].rev,
151 intel_platform_name(fw_blobs[i].p),
152 fw_blobs[i].rev);
153
154 uc_fw->path = NULL;
155 }
156 }
157}
158
159static const char *__override_guc_firmware_path(struct drm_i915_private *i915)
160{
161 if (i915->params.enable_guc & ENABLE_GUC_MASK)
162 return i915->params.guc_firmware_path;
163 return "";
164}
165
166static const char *__override_huc_firmware_path(struct drm_i915_private *i915)
167{
168 if (i915->params.enable_guc & ENABLE_GUC_LOAD_HUC)
169 return i915->params.huc_firmware_path;
170 return "";
171}
172
173static void __uc_fw_user_override(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
174{
175 const char *path = NULL;
176
177 switch (uc_fw->type) {
178 case INTEL_UC_FW_TYPE_GUC:
179 path = __override_guc_firmware_path(i915);
180 break;
181 case INTEL_UC_FW_TYPE_HUC:
182 path = __override_huc_firmware_path(i915);
183 break;
184 }
185
186 if (unlikely(path)) {
187 uc_fw->path = path;
188 uc_fw->user_overridden = true;
189 }
190}
191
192
193
194
195
196
197
198
199
200void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw,
201 enum intel_uc_fw_type type)
202{
203 struct drm_i915_private *i915 = ____uc_fw_to_gt(uc_fw, type)->i915;
204
205
206
207
208
209 BUILD_BUG_ON(INTEL_UC_FIRMWARE_UNINITIALIZED);
210 GEM_BUG_ON(uc_fw->status);
211 GEM_BUG_ON(uc_fw->path);
212
213 uc_fw->type = type;
214
215 if (HAS_GT_UC(i915)) {
216 __uc_fw_auto_select(i915, uc_fw);
217 __uc_fw_user_override(i915, uc_fw);
218 }
219
220 intel_uc_fw_change_status(uc_fw, uc_fw->path ? *uc_fw->path ?
221 INTEL_UC_FIRMWARE_SELECTED :
222 INTEL_UC_FIRMWARE_DISABLED :
223 INTEL_UC_FIRMWARE_NOT_SUPPORTED);
224}
225
226static void __force_fw_fetch_failures(struct intel_uc_fw *uc_fw, int e)
227{
228 struct drm_i915_private *i915 = __uc_fw_to_gt(uc_fw)->i915;
229 bool user = e == -EINVAL;
230
231 if (i915_inject_probe_error(i915, e)) {
232
233 uc_fw->path = "<invalid>";
234 uc_fw->user_overridden = user;
235 } else if (i915_inject_probe_error(i915, e)) {
236
237 uc_fw->major_ver_wanted += 1;
238 uc_fw->minor_ver_wanted = 0;
239 uc_fw->user_overridden = user;
240 } else if (i915_inject_probe_error(i915, e)) {
241
242 uc_fw->minor_ver_wanted += 1;
243 uc_fw->user_overridden = user;
244 } else if (uc_fw->major_ver_wanted &&
245 i915_inject_probe_error(i915, e)) {
246
247 uc_fw->major_ver_wanted -= 1;
248 uc_fw->minor_ver_wanted = 0;
249 uc_fw->user_overridden = user;
250 } else if (uc_fw->minor_ver_wanted &&
251 i915_inject_probe_error(i915, e)) {
252
253 uc_fw->minor_ver_wanted -= 1;
254 uc_fw->user_overridden = user;
255 } else if (user && i915_inject_probe_error(i915, e)) {
256
257 uc_fw->major_ver_wanted = 0;
258 uc_fw->minor_ver_wanted = 0;
259 uc_fw->user_overridden = true;
260 }
261}
262
263
264
265
266
267
268
269
270
271int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
272{
273 struct drm_i915_private *i915 = __uc_fw_to_gt(uc_fw)->i915;
274 struct device *dev = i915->drm.dev;
275 struct drm_i915_gem_object *obj;
276 const struct firmware *fw = NULL;
277 struct uc_css_header *css;
278 size_t size;
279 int err;
280
281 GEM_BUG_ON(!i915->wopcm.size);
282 GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw));
283
284 err = i915_inject_probe_error(i915, -ENXIO);
285 if (err)
286 goto fail;
287
288 __force_fw_fetch_failures(uc_fw, -EINVAL);
289 __force_fw_fetch_failures(uc_fw, -ESTALE);
290
291 err = request_firmware(&fw, uc_fw->path, dev);
292 if (err)
293 goto fail;
294
295
296 if (unlikely(fw->size < sizeof(struct uc_css_header))) {
297 drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu < %zu\n",
298 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
299 fw->size, sizeof(struct uc_css_header));
300 err = -ENODATA;
301 goto fail;
302 }
303
304 css = (struct uc_css_header *)fw->data;
305
306
307 size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw -
308 css->exponent_size_dw) * sizeof(u32);
309 if (unlikely(size != sizeof(struct uc_css_header))) {
310 drm_warn(&i915->drm,
311 "%s firmware %s: unexpected header size: %zu != %zu\n",
312 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
313 fw->size, sizeof(struct uc_css_header));
314 err = -EPROTO;
315 goto fail;
316 }
317
318
319 uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
320
321
322 if (unlikely(css->key_size_dw != UOS_RSA_SCRATCH_COUNT)) {
323 drm_warn(&i915->drm, "%s firmware %s: unexpected key size: %u != %u\n",
324 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
325 css->key_size_dw, UOS_RSA_SCRATCH_COUNT);
326 err = -EPROTO;
327 goto fail;
328 }
329 uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
330
331
332 size = sizeof(struct uc_css_header) + uc_fw->ucode_size + uc_fw->rsa_size;
333 if (unlikely(fw->size < size)) {
334 drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu < %zu\n",
335 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
336 fw->size, size);
337 err = -ENOEXEC;
338 goto fail;
339 }
340
341
342 size = __intel_uc_fw_get_upload_size(uc_fw);
343 if (unlikely(size >= i915->wopcm.size)) {
344 drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu > %zu\n",
345 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
346 size, (size_t)i915->wopcm.size);
347 err = -E2BIG;
348 goto fail;
349 }
350
351
352 uc_fw->major_ver_found = FIELD_GET(CSS_SW_VERSION_UC_MAJOR,
353 css->sw_version);
354 uc_fw->minor_ver_found = FIELD_GET(CSS_SW_VERSION_UC_MINOR,
355 css->sw_version);
356
357 if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
358 uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
359 drm_notice(&i915->drm, "%s firmware %s: unexpected version: %u.%u != %u.%u\n",
360 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
361 uc_fw->major_ver_found, uc_fw->minor_ver_found,
362 uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
363 if (!intel_uc_fw_is_overridden(uc_fw)) {
364 err = -ENOEXEC;
365 goto fail;
366 }
367 }
368
369 if (uc_fw->type == INTEL_UC_FW_TYPE_GUC)
370 uc_fw->private_data_size = css->private_data_size;
371
372 obj = i915_gem_object_create_shmem_from_data(i915, fw->data, fw->size);
373 if (IS_ERR(obj)) {
374 err = PTR_ERR(obj);
375 goto fail;
376 }
377
378 uc_fw->obj = obj;
379 uc_fw->size = fw->size;
380 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE);
381
382 release_firmware(fw);
383 return 0;
384
385fail:
386 intel_uc_fw_change_status(uc_fw, err == -ENOENT ?
387 INTEL_UC_FIRMWARE_MISSING :
388 INTEL_UC_FIRMWARE_ERROR);
389
390 drm_notice(&i915->drm, "%s firmware %s: fetch failed with error %d\n",
391 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);
392 drm_info(&i915->drm, "%s firmware(s) can be downloaded from %s\n",
393 intel_uc_fw_type_repr(uc_fw->type), INTEL_UC_FIRMWARE_URL);
394
395 release_firmware(fw);
396 return err;
397}
398
399static u32 uc_fw_ggtt_offset(struct intel_uc_fw *uc_fw)
400{
401 struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
402 struct drm_mm_node *node = &ggtt->uc_fw;
403
404 GEM_BUG_ON(!drm_mm_node_allocated(node));
405 GEM_BUG_ON(upper_32_bits(node->start));
406 GEM_BUG_ON(upper_32_bits(node->start + node->size - 1));
407
408 return lower_32_bits(node->start);
409}
410
411static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw)
412{
413 struct drm_i915_gem_object *obj = uc_fw->obj;
414 struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
415 struct i915_vma dummy = {
416 .node.start = uc_fw_ggtt_offset(uc_fw),
417 .node.size = obj->base.size,
418 .pages = obj->mm.pages,
419 .vm = &ggtt->vm,
420 };
421
422 GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
423 GEM_BUG_ON(dummy.node.size > ggtt->uc_fw.size);
424
425
426 drm_clflush_sg(dummy.pages);
427
428 ggtt->vm.insert_entries(&ggtt->vm, &dummy, I915_CACHE_NONE, 0);
429}
430
431static void uc_fw_unbind_ggtt(struct intel_uc_fw *uc_fw)
432{
433 struct drm_i915_gem_object *obj = uc_fw->obj;
434 struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt;
435 u64 start = uc_fw_ggtt_offset(uc_fw);
436
437 ggtt->vm.clear_range(&ggtt->vm, start, obj->base.size);
438}
439
440static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
441{
442 struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
443 struct intel_uncore *uncore = gt->uncore;
444 u64 offset;
445 int ret;
446
447 ret = i915_inject_probe_error(gt->i915, -ETIMEDOUT);
448 if (ret)
449 return ret;
450
451 intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
452
453
454 offset = uc_fw_ggtt_offset(uc_fw);
455 GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000);
456 intel_uncore_write_fw(uncore, DMA_ADDR_0_LOW, lower_32_bits(offset));
457 intel_uncore_write_fw(uncore, DMA_ADDR_0_HIGH, upper_32_bits(offset));
458
459
460 intel_uncore_write_fw(uncore, DMA_ADDR_1_LOW, dst_offset);
461 intel_uncore_write_fw(uncore, DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
462
463
464
465
466
467 intel_uncore_write_fw(uncore, DMA_COPY_SIZE,
468 sizeof(struct uc_css_header) + uc_fw->ucode_size);
469
470
471 intel_uncore_write_fw(uncore, DMA_CTRL,
472 _MASKED_BIT_ENABLE(dma_flags | START_DMA));
473
474
475 ret = intel_wait_for_register_fw(uncore, DMA_CTRL, START_DMA, 0, 100);
476 if (ret)
477 drm_err(>->i915->drm, "DMA for %s fw failed, DMA_CTRL=%u\n",
478 intel_uc_fw_type_repr(uc_fw->type),
479 intel_uncore_read_fw(uncore, DMA_CTRL));
480
481
482 intel_uncore_write_fw(uncore, DMA_CTRL, _MASKED_BIT_DISABLE(dma_flags));
483
484 intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
485
486 return ret;
487}
488
489
490
491
492
493
494
495
496
497
498
499int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags)
500{
501 struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
502 int err;
503
504
505 GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw));
506
507 err = i915_inject_probe_error(gt->i915, -ENOEXEC);
508 if (err)
509 return err;
510
511 if (!intel_uc_fw_is_loadable(uc_fw))
512 return -ENOEXEC;
513
514
515 uc_fw_bind_ggtt(uc_fw);
516 err = uc_fw_xfer(uc_fw, dst_offset, dma_flags);
517 uc_fw_unbind_ggtt(uc_fw);
518 if (err)
519 goto fail;
520
521 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_TRANSFERRED);
522 return 0;
523
524fail:
525 i915_probe_error(gt->i915, "Failed to load %s firmware %s (%d)\n",
526 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path,
527 err);
528 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_FAIL);
529 return err;
530}
531
532int intel_uc_fw_init(struct intel_uc_fw *uc_fw)
533{
534 int err;
535
536
537 GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw));
538
539 if (!intel_uc_fw_is_available(uc_fw))
540 return -ENOEXEC;
541
542 err = i915_gem_object_pin_pages(uc_fw->obj);
543 if (err) {
544 DRM_DEBUG_DRIVER("%s fw pin-pages err=%d\n",
545 intel_uc_fw_type_repr(uc_fw->type), err);
546 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_FAIL);
547 }
548
549 return err;
550}
551
552void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
553{
554 if (i915_gem_object_has_pinned_pages(uc_fw->obj))
555 i915_gem_object_unpin_pages(uc_fw->obj);
556
557 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE);
558}
559
560
561
562
563
564
565
566void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw)
567{
568 if (!intel_uc_fw_is_available(uc_fw))
569 return;
570
571 i915_gem_object_put(fetch_and_zero(&uc_fw->obj));
572
573 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_SELECTED);
574}
575
576
577
578
579
580
581
582
583
584
585size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len)
586{
587 struct sg_table *pages = uc_fw->obj->mm.pages;
588 u32 size = min_t(u32, uc_fw->rsa_size, max_len);
589 u32 offset = sizeof(struct uc_css_header) + uc_fw->ucode_size;
590
591 GEM_BUG_ON(!intel_uc_fw_is_available(uc_fw));
592
593 return sg_pcopy_to_buffer(pages->sgl, pages->nents, dst, size, offset);
594}
595
596
597
598
599
600
601
602
603void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p)
604{
605 drm_printf(p, "%s firmware: %s\n",
606 intel_uc_fw_type_repr(uc_fw->type), uc_fw->path);
607 drm_printf(p, "\tstatus: %s\n",
608 intel_uc_fw_status_repr(uc_fw->status));
609 drm_printf(p, "\tversion: wanted %u.%u, found %u.%u\n",
610 uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted,
611 uc_fw->major_ver_found, uc_fw->minor_ver_found);
612 drm_printf(p, "\tuCode: %u bytes\n", uc_fw->ucode_size);
613 drm_printf(p, "\tRSA: %u bytes\n", uc_fw->rsa_size);
614}
615