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