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, 12, 1)) \ 92 fw_def(DG2, 0, guc_maj(dg2, 70, 12, 1)) \ 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 __force_fw_fetch_failures(struct intel_uc_fw *uc_fw, int e) 546 { 547 struct drm_i915_private *i915 = __uc_fw_to_gt(uc_fw)->i915; 548 bool user = e == -EINVAL; 549 550 if (i915_inject_probe_error(i915, e)) { 551 /* non-existing blob */ 552 uc_fw->file_selected.path = "<invalid>"; 553 uc_fw->user_overridden = user; 554 } else if (i915_inject_probe_error(i915, e)) { 555 /* require next major version */ 556 uc_fw->file_wanted.ver.major += 1; 557 uc_fw->file_wanted.ver.minor = 0; 558 uc_fw->user_overridden = user; 559 } else if (i915_inject_probe_error(i915, e)) { 560 /* require next minor version */ 561 uc_fw->file_wanted.ver.minor += 1; 562 uc_fw->user_overridden = user; 563 } else if (uc_fw->file_wanted.ver.major && 564 i915_inject_probe_error(i915, e)) { 565 /* require prev major version */ 566 uc_fw->file_wanted.ver.major -= 1; 567 uc_fw->file_wanted.ver.minor = 0; 568 uc_fw->user_overridden = user; 569 } else if (uc_fw->file_wanted.ver.minor && 570 i915_inject_probe_error(i915, e)) { 571 /* require prev minor version - hey, this should work! */ 572 uc_fw->file_wanted.ver.minor -= 1; 573 uc_fw->user_overridden = user; 574 } else if (user && i915_inject_probe_error(i915, e)) { 575 /* officially unsupported platform */ 576 uc_fw->file_wanted.ver.major = 0; 577 uc_fw->file_wanted.ver.minor = 0; 578 uc_fw->user_overridden = true; 579 } 580 } 581 582 static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32 css_value) 583 { 584 /* Get version numbers from the CSS header */ 585 ver->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css_value); 586 ver->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css_value); 587 ver->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css_value); 588 } 589 590 static void guc_read_css_info(struct intel_uc_fw *uc_fw, struct uc_css_header *css) 591 { 592 struct intel_guc *guc = container_of(uc_fw, struct intel_guc, fw); 593 594 /* 595 * The GuC firmware includes an extra version number to specify the 596 * submission API level. This allows submission code to work with 597 * multiple GuC versions without having to know the absolute firmware 598 * version number (there are likely to be multiple firmware releases 599 * which all support the same submission API level). 600 * 601 * Note that the spec for the CSS header defines this version number 602 * as 'vf_version' as it was originally intended for virtualisation. 603 * However, it is applicable to native submission as well. 604 * 605 * Unfortunately, due to an oversight, this version number was only 606 * exposed in the CSS header from v70.6.0. 607 */ 608 if (uc_fw->file_selected.ver.major >= 70) { 609 if (uc_fw->file_selected.ver.minor >= 6) { 610 /* v70.6.0 adds CSS header support */ 611 uc_unpack_css_version(&guc->submission_version, css->vf_version); 612 } else if (uc_fw->file_selected.ver.minor >= 3) { 613 /* v70.3.0 introduced v1.1.0 */ 614 guc->submission_version.major = 1; 615 guc->submission_version.minor = 1; 616 guc->submission_version.patch = 0; 617 } else { 618 /* v70.0.0 introduced v1.0.0 */ 619 guc->submission_version.major = 1; 620 guc->submission_version.minor = 0; 621 guc->submission_version.patch = 0; 622 } 623 } else if (uc_fw->file_selected.ver.major >= 69) { 624 /* v69.0.0 introduced v0.10.0 */ 625 guc->submission_version.major = 0; 626 guc->submission_version.minor = 10; 627 guc->submission_version.patch = 0; 628 } else { 629 /* Prior versions were v0.1.0 */ 630 guc->submission_version.major = 0; 631 guc->submission_version.minor = 1; 632 guc->submission_version.patch = 0; 633 } 634 635 uc_fw->private_data_size = css->private_data_size; 636 } 637 638 static int __check_ccs_header(struct intel_gt *gt, 639 const void *fw_data, size_t fw_size, 640 struct intel_uc_fw *uc_fw) 641 { 642 struct uc_css_header *css; 643 size_t size; 644 645 /* Check the size of the blob before examining buffer contents */ 646 if (unlikely(fw_size < sizeof(struct uc_css_header))) { 647 gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n", 648 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, 649 fw_size, sizeof(struct uc_css_header)); 650 return -ENODATA; 651 } 652 653 css = (struct uc_css_header *)fw_data; 654 655 /* Check integrity of size values inside CSS header */ 656 size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw - 657 css->exponent_size_dw) * sizeof(u32); 658 if (unlikely(size != sizeof(struct uc_css_header))) { 659 gt_warn(gt, "%s firmware %s: unexpected header size: %zu != %zu\n", 660 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, 661 fw_size, sizeof(struct uc_css_header)); 662 return -EPROTO; 663 } 664 665 /* uCode size must calculated from other sizes */ 666 uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32); 667 668 /* now RSA */ 669 uc_fw->rsa_size = css->key_size_dw * sizeof(u32); 670 671 /* At least, it should have header, uCode and RSA. Size of all three. */ 672 size = sizeof(struct uc_css_header) + uc_fw->ucode_size + uc_fw->rsa_size; 673 if (unlikely(fw_size < size)) { 674 gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n", 675 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, 676 fw_size, size); 677 return -ENOEXEC; 678 } 679 680 /* Sanity check whether this fw is not larger than whole WOPCM memory */ 681 size = __intel_uc_fw_get_upload_size(uc_fw); 682 if (unlikely(size >= gt->wopcm.size)) { 683 gt_warn(gt, "%s firmware %s: invalid size: %zu > %zu\n", 684 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, 685 size, (size_t)gt->wopcm.size); 686 return -E2BIG; 687 } 688 689 uc_unpack_css_version(&uc_fw->file_selected.ver, css->sw_version); 690 691 if (uc_fw->type == INTEL_UC_FW_TYPE_GUC) 692 guc_read_css_info(uc_fw, css); 693 694 return 0; 695 } 696 697 static int check_gsc_manifest(struct intel_gt *gt, 698 const struct firmware *fw, 699 struct intel_uc_fw *uc_fw) 700 { 701 switch (uc_fw->type) { 702 case INTEL_UC_FW_TYPE_HUC: 703 intel_huc_fw_get_binary_info(uc_fw, fw->data, fw->size); 704 break; 705 case INTEL_UC_FW_TYPE_GSC: 706 intel_gsc_fw_get_binary_info(uc_fw, fw->data, fw->size); 707 break; 708 default: 709 MISSING_CASE(uc_fw->type); 710 return -EINVAL; 711 } 712 713 if (uc_fw->dma_start_offset) { 714 u32 delta = uc_fw->dma_start_offset; 715 716 __check_ccs_header(gt, fw->data + delta, fw->size - delta, uc_fw); 717 } 718 719 return 0; 720 } 721 722 static int check_ccs_header(struct intel_gt *gt, 723 const struct firmware *fw, 724 struct intel_uc_fw *uc_fw) 725 { 726 return __check_ccs_header(gt, fw->data, fw->size, uc_fw); 727 } 728 729 static bool is_ver_8bit(struct intel_uc_fw_ver *ver) 730 { 731 return ver->major < 0xFF && ver->minor < 0xFF && ver->patch < 0xFF; 732 } 733 734 static int guc_check_version_range(struct intel_uc_fw *uc_fw) 735 { 736 struct intel_guc *guc = container_of(uc_fw, struct intel_guc, fw); 737 struct intel_gt *gt = __uc_fw_to_gt(uc_fw); 738 739 /* 740 * GuC version number components are defined as being 8-bits. 741 * The submission code relies on this to optimise version comparison 742 * tests. So enforce the restriction here. 743 */ 744 745 if (!is_ver_8bit(&uc_fw->file_selected.ver)) { 746 gt_warn(gt, "%s firmware: invalid file version: 0x%02X:%02X:%02X\n", 747 intel_uc_fw_type_repr(uc_fw->type), 748 uc_fw->file_selected.ver.major, 749 uc_fw->file_selected.ver.minor, 750 uc_fw->file_selected.ver.patch); 751 return -EINVAL; 752 } 753 754 if (!is_ver_8bit(&guc->submission_version)) { 755 gt_warn(gt, "%s firmware: invalid submit version: 0x%02X:%02X:%02X\n", 756 intel_uc_fw_type_repr(uc_fw->type), 757 guc->submission_version.major, 758 guc->submission_version.minor, 759 guc->submission_version.patch); 760 return -EINVAL; 761 } 762 763 return i915_inject_probe_error(gt->i915, -EINVAL); 764 } 765 766 static int check_fw_header(struct intel_gt *gt, 767 const struct firmware *fw, 768 struct intel_uc_fw *uc_fw) 769 { 770 int err = 0; 771 772 if (uc_fw->has_gsc_headers) 773 err = check_gsc_manifest(gt, fw, uc_fw); 774 else 775 err = check_ccs_header(gt, fw, uc_fw); 776 if (err) 777 return err; 778 779 return 0; 780 } 781 782 static int try_firmware_load(struct intel_uc_fw *uc_fw, const struct firmware **fw) 783 { 784 struct intel_gt *gt = __uc_fw_to_gt(uc_fw); 785 struct device *dev = gt->i915->drm.dev; 786 int err; 787 788 err = firmware_request_nowarn(fw, uc_fw->file_selected.path, dev); 789 790 if (err) 791 return err; 792 793 if (uc_fw->needs_ggtt_mapping && (*fw)->size > INTEL_UC_RSVD_GGTT_PER_FW) { 794 gt_err(gt, "%s firmware %s: size (%zuKB) exceeds max supported size (%uKB)\n", 795 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, 796 (*fw)->size / SZ_1K, INTEL_UC_RSVD_GGTT_PER_FW / SZ_1K); 797 798 /* try to find another blob to load */ 799 release_firmware(*fw); 800 *fw = NULL; 801 return -ENOENT; 802 } 803 804 return 0; 805 } 806 807 static int check_mtl_huc_guc_compatibility(struct intel_gt *gt, 808 struct intel_uc_fw_file *huc_selected) 809 { 810 struct intel_uc_fw_file *guc_selected = >->uc.guc.fw.file_selected; 811 struct intel_uc_fw_ver *huc_ver = &huc_selected->ver; 812 struct intel_uc_fw_ver *guc_ver = &guc_selected->ver; 813 bool new_huc, new_guc; 814 815 /* we can only do this check after having fetched both GuC and HuC */ 816 GEM_BUG_ON(!huc_selected->path || !guc_selected->path); 817 818 /* 819 * Due to changes in the authentication flow for MTL, HuC 8.5.1 or newer 820 * requires GuC 70.7.0 or newer. Older HuC binaries will instead require 821 * GuC < 70.7.0. 822 */ 823 new_huc = huc_ver->major > 8 || 824 (huc_ver->major == 8 && huc_ver->minor > 5) || 825 (huc_ver->major == 8 && huc_ver->minor == 5 && huc_ver->patch >= 1); 826 827 new_guc = guc_ver->major > 70 || 828 (guc_ver->major == 70 && guc_ver->minor >= 7); 829 830 if (new_huc != new_guc) { 831 UNEXPECTED(gt, "HuC %u.%u.%u is incompatible with GuC %u.%u.%u\n", 832 huc_ver->major, huc_ver->minor, huc_ver->patch, 833 guc_ver->major, guc_ver->minor, guc_ver->patch); 834 gt_info(gt, "MTL GuC 70.7.0+ and HuC 8.5.1+ don't work with older releases\n"); 835 return -ENOEXEC; 836 } 837 838 return 0; 839 } 840 841 int intel_uc_check_file_version(struct intel_uc_fw *uc_fw, bool *old_ver) 842 { 843 struct intel_gt *gt = __uc_fw_to_gt(uc_fw); 844 struct intel_uc_fw_file *wanted = &uc_fw->file_wanted; 845 struct intel_uc_fw_file *selected = &uc_fw->file_selected; 846 int ret; 847 848 /* 849 * MTL has some compatibility issues with early GuC/HuC binaries 850 * not working with newer ones. This is specific to MTL and we 851 * don't expect it to extend to other platforms. 852 */ 853 if (IS_METEORLAKE(gt->i915) && uc_fw->type == INTEL_UC_FW_TYPE_HUC) { 854 ret = check_mtl_huc_guc_compatibility(gt, selected); 855 if (ret) 856 return ret; 857 } 858 859 if (!wanted->ver.major || !selected->ver.major) 860 return 0; 861 862 /* Check the file's major version was as it claimed */ 863 if (selected->ver.major != wanted->ver.major) { 864 UNEXPECTED(gt, "%s firmware %s: unexpected version: %u.%u != %u.%u\n", 865 intel_uc_fw_type_repr(uc_fw->type), selected->path, 866 selected->ver.major, selected->ver.minor, 867 wanted->ver.major, wanted->ver.minor); 868 if (!intel_uc_fw_is_overridden(uc_fw)) 869 return -ENOEXEC; 870 } else if (old_ver) { 871 if (selected->ver.minor < wanted->ver.minor) 872 *old_ver = true; 873 else if ((selected->ver.minor == wanted->ver.minor) && 874 (selected->ver.patch < wanted->ver.patch)) 875 *old_ver = true; 876 } 877 878 return 0; 879 } 880 881 /** 882 * intel_uc_fw_fetch - fetch uC firmware 883 * @uc_fw: uC firmware 884 * 885 * Fetch uC firmware into GEM obj. 886 * 887 * Return: 0 on success, a negative errno code on failure. 888 */ 889 int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw) 890 { 891 struct intel_gt *gt = __uc_fw_to_gt(uc_fw); 892 struct drm_i915_private *i915 = gt->i915; 893 struct intel_uc_fw_file file_ideal; 894 struct drm_i915_gem_object *obj; 895 const struct firmware *fw = NULL; 896 bool old_ver = false; 897 int err; 898 899 GEM_BUG_ON(!gt->wopcm.size); 900 GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw)); 901 902 err = i915_inject_probe_error(i915, -ENXIO); 903 if (err) 904 goto fail; 905 906 __force_fw_fetch_failures(uc_fw, -EINVAL); 907 __force_fw_fetch_failures(uc_fw, -ESTALE); 908 909 err = try_firmware_load(uc_fw, &fw); 910 memcpy(&file_ideal, &uc_fw->file_wanted, sizeof(file_ideal)); 911 912 /* Any error is terminal if overriding. Don't bother searching for older versions */ 913 if (err && intel_uc_fw_is_overridden(uc_fw)) 914 goto fail; 915 916 while (err == -ENOENT) { 917 old_ver = true; 918 919 __uc_fw_auto_select(i915, uc_fw); 920 if (!uc_fw->file_selected.path) { 921 /* 922 * No more options! But set the path back to something 923 * valid just in case it gets dereferenced. 924 */ 925 uc_fw->file_selected.path = file_ideal.path; 926 927 /* Also, preserve the version that was really wanted */ 928 memcpy(&uc_fw->file_wanted, &file_ideal, sizeof(uc_fw->file_wanted)); 929 break; 930 } 931 932 err = try_firmware_load(uc_fw, &fw); 933 } 934 935 if (err) 936 goto fail; 937 938 err = check_fw_header(gt, fw, uc_fw); 939 if (err) 940 goto fail; 941 942 if (uc_fw->type == INTEL_UC_FW_TYPE_GUC) { 943 err = guc_check_version_range(uc_fw); 944 if (err) 945 goto fail; 946 } 947 948 err = intel_uc_check_file_version(uc_fw, &old_ver); 949 if (err) 950 goto fail; 951 952 if (old_ver && uc_fw->file_selected.ver.major) { 953 /* Preserve the version that was really wanted */ 954 memcpy(&uc_fw->file_wanted, &file_ideal, sizeof(uc_fw->file_wanted)); 955 956 UNEXPECTED(gt, "%s firmware %s (%d.%d.%d) is recommended, but only %s (%d.%d.%d) was found\n", 957 intel_uc_fw_type_repr(uc_fw->type), 958 uc_fw->file_wanted.path, 959 uc_fw->file_wanted.ver.major, 960 uc_fw->file_wanted.ver.minor, 961 uc_fw->file_wanted.ver.patch, 962 uc_fw->file_selected.path, 963 uc_fw->file_selected.ver.major, 964 uc_fw->file_selected.ver.minor, 965 uc_fw->file_selected.ver.patch); 966 gt_info(gt, "Consider updating your linux-firmware pkg or downloading from %s\n", 967 INTEL_UC_FIRMWARE_URL); 968 } 969 970 if (HAS_LMEM(i915)) { 971 obj = i915_gem_object_create_lmem_from_data(i915, fw->data, fw->size); 972 if (!IS_ERR(obj)) 973 obj->flags |= I915_BO_ALLOC_PM_EARLY; 974 } else { 975 obj = i915_gem_object_create_shmem_from_data(i915, fw->data, fw->size); 976 } 977 978 if (IS_ERR(obj)) { 979 err = PTR_ERR(obj); 980 goto fail; 981 } 982 983 uc_fw->obj = obj; 984 uc_fw->size = fw->size; 985 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE); 986 987 release_firmware(fw); 988 return 0; 989 990 fail: 991 intel_uc_fw_change_status(uc_fw, err == -ENOENT ? 992 INTEL_UC_FIRMWARE_MISSING : 993 INTEL_UC_FIRMWARE_ERROR); 994 995 gt_probe_error(gt, "%s firmware %s: fetch failed %pe\n", 996 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, ERR_PTR(err)); 997 gt_info(gt, "%s firmware(s) can be downloaded from %s\n", 998 intel_uc_fw_type_repr(uc_fw->type), INTEL_UC_FIRMWARE_URL); 999 1000 release_firmware(fw); /* OK even if fw is NULL */ 1001 return err; 1002 } 1003 1004 static u32 uc_fw_ggtt_offset(struct intel_uc_fw *uc_fw) 1005 { 1006 struct intel_gt *gt = __uc_fw_to_gt(uc_fw); 1007 struct i915_ggtt *ggtt = gt->ggtt; 1008 struct drm_mm_node *node = &ggtt->uc_fw; 1009 u32 offset = uc_fw->type * INTEL_UC_RSVD_GGTT_PER_FW; 1010 1011 /* 1012 * The media GT shares the GGTT with the root GT, which means that 1013 * we need to use different offsets for the binaries on the media GT. 1014 * To keep the math simple, we use 8MB for the root tile and 8MB for 1015 * the media one. This will need to be updated if we ever have more 1016 * than 1 media GT. 1017 */ 1018 BUILD_BUG_ON(INTEL_UC_FW_NUM_TYPES * INTEL_UC_RSVD_GGTT_PER_FW > SZ_8M); 1019 GEM_BUG_ON(gt->type == GT_MEDIA && gt->info.id > 1); 1020 if (gt->type == GT_MEDIA) 1021 offset += SZ_8M; 1022 1023 GEM_BUG_ON(!drm_mm_node_allocated(node)); 1024 GEM_BUG_ON(upper_32_bits(node->start)); 1025 GEM_BUG_ON(upper_32_bits(node->start + node->size - 1)); 1026 GEM_BUG_ON(offset + uc_fw->obj->base.size > node->size); 1027 GEM_BUG_ON(uc_fw->obj->base.size > INTEL_UC_RSVD_GGTT_PER_FW); 1028 1029 return lower_32_bits(node->start + offset); 1030 } 1031 1032 static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw) 1033 { 1034 struct drm_i915_gem_object *obj = uc_fw->obj; 1035 struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt; 1036 struct i915_vma_resource *vma_res = &uc_fw->vma_res; 1037 u32 pte_flags = 0; 1038 1039 if (!uc_fw->needs_ggtt_mapping) 1040 return; 1041 1042 vma_res->start = uc_fw_ggtt_offset(uc_fw); 1043 vma_res->node_size = obj->base.size; 1044 vma_res->bi.pages = obj->mm.pages; 1045 1046 GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); 1047 1048 /* uc_fw->obj cache domains were not controlled across suspend */ 1049 if (i915_gem_object_has_struct_page(obj)) 1050 drm_clflush_sg(vma_res->bi.pages); 1051 1052 if (i915_gem_object_is_lmem(obj)) 1053 pte_flags |= PTE_LM; 1054 1055 if (ggtt->vm.raw_insert_entries) 1056 ggtt->vm.raw_insert_entries(&ggtt->vm, vma_res, 1057 i915_gem_get_pat_index(ggtt->vm.i915, 1058 I915_CACHE_NONE), 1059 pte_flags); 1060 else 1061 ggtt->vm.insert_entries(&ggtt->vm, vma_res, 1062 i915_gem_get_pat_index(ggtt->vm.i915, 1063 I915_CACHE_NONE), 1064 pte_flags); 1065 } 1066 1067 static void uc_fw_unbind_ggtt(struct intel_uc_fw *uc_fw) 1068 { 1069 struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt; 1070 struct i915_vma_resource *vma_res = &uc_fw->vma_res; 1071 1072 if (!vma_res->node_size) 1073 return; 1074 1075 ggtt->vm.clear_range(&ggtt->vm, vma_res->start, vma_res->node_size); 1076 } 1077 1078 static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags) 1079 { 1080 struct intel_gt *gt = __uc_fw_to_gt(uc_fw); 1081 struct intel_uncore *uncore = gt->uncore; 1082 u64 offset; 1083 int ret; 1084 1085 ret = i915_inject_probe_error(gt->i915, -ETIMEDOUT); 1086 if (ret) 1087 return ret; 1088 1089 intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); 1090 1091 /* Set the source address for the uCode */ 1092 offset = uc_fw->vma_res.start + uc_fw->dma_start_offset; 1093 GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000); 1094 intel_uncore_write_fw(uncore, DMA_ADDR_0_LOW, lower_32_bits(offset)); 1095 intel_uncore_write_fw(uncore, DMA_ADDR_0_HIGH, upper_32_bits(offset)); 1096 1097 /* Set the DMA destination */ 1098 intel_uncore_write_fw(uncore, DMA_ADDR_1_LOW, dst_offset); 1099 intel_uncore_write_fw(uncore, DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM); 1100 1101 /* 1102 * Set the transfer size. The header plus uCode will be copied to WOPCM 1103 * via DMA, excluding any other components 1104 */ 1105 intel_uncore_write_fw(uncore, DMA_COPY_SIZE, 1106 sizeof(struct uc_css_header) + uc_fw->ucode_size); 1107 1108 /* Start the DMA */ 1109 intel_uncore_write_fw(uncore, DMA_CTRL, 1110 _MASKED_BIT_ENABLE(dma_flags | START_DMA)); 1111 1112 /* Wait for DMA to finish */ 1113 ret = intel_wait_for_register_fw(uncore, DMA_CTRL, START_DMA, 0, 100); 1114 if (ret) 1115 gt_err(gt, "DMA for %s fw failed, DMA_CTRL=%u\n", 1116 intel_uc_fw_type_repr(uc_fw->type), 1117 intel_uncore_read_fw(uncore, DMA_CTRL)); 1118 1119 /* Disable the bits once DMA is over */ 1120 intel_uncore_write_fw(uncore, DMA_CTRL, _MASKED_BIT_DISABLE(dma_flags)); 1121 1122 intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL); 1123 1124 return ret; 1125 } 1126 1127 int intel_uc_fw_mark_load_failed(struct intel_uc_fw *uc_fw, int err) 1128 { 1129 struct intel_gt *gt = __uc_fw_to_gt(uc_fw); 1130 1131 GEM_BUG_ON(!intel_uc_fw_is_loadable(uc_fw)); 1132 1133 gt_probe_error(gt, "Failed to load %s firmware %s %pe\n", 1134 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, ERR_PTR(err)); 1135 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_LOAD_FAIL); 1136 1137 return err; 1138 } 1139 1140 /** 1141 * intel_uc_fw_upload - load uC firmware using custom loader 1142 * @uc_fw: uC firmware 1143 * @dst_offset: destination offset 1144 * @dma_flags: flags for flags for dma ctrl 1145 * 1146 * Loads uC firmware and updates internal flags. 1147 * 1148 * Return: 0 on success, non-zero on failure. 1149 */ 1150 int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags) 1151 { 1152 struct intel_gt *gt = __uc_fw_to_gt(uc_fw); 1153 int err; 1154 1155 /* make sure the status was cleared the last time we reset the uc */ 1156 GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw)); 1157 1158 err = i915_inject_probe_error(gt->i915, -ENOEXEC); 1159 if (err) 1160 return err; 1161 1162 if (!intel_uc_fw_is_loadable(uc_fw)) 1163 return -ENOEXEC; 1164 1165 /* Call custom loader */ 1166 err = uc_fw_xfer(uc_fw, dst_offset, dma_flags); 1167 if (err) 1168 goto fail; 1169 1170 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_TRANSFERRED); 1171 return 0; 1172 1173 fail: 1174 return intel_uc_fw_mark_load_failed(uc_fw, err); 1175 } 1176 1177 static inline bool uc_fw_need_rsa_in_memory(struct intel_uc_fw *uc_fw) 1178 { 1179 /* 1180 * The HW reads the GuC RSA from memory if the key size is > 256 bytes, 1181 * while it reads it from the 64 RSA registers if it is smaller. 1182 * The HuC RSA is always read from memory. 1183 */ 1184 return uc_fw->type == INTEL_UC_FW_TYPE_HUC || uc_fw->rsa_size > 256; 1185 } 1186 1187 static int uc_fw_rsa_data_create(struct intel_uc_fw *uc_fw) 1188 { 1189 struct intel_gt *gt = __uc_fw_to_gt(uc_fw); 1190 struct i915_vma *vma; 1191 size_t copied; 1192 void *vaddr; 1193 int err; 1194 1195 err = i915_inject_probe_error(gt->i915, -ENXIO); 1196 if (err) 1197 return err; 1198 1199 if (!uc_fw_need_rsa_in_memory(uc_fw)) 1200 return 0; 1201 1202 /* 1203 * uC firmwares will sit above GUC_GGTT_TOP and will not map through 1204 * GGTT. Unfortunately, this means that the GuC HW cannot perform the uC 1205 * authentication from memory, as the RSA offset now falls within the 1206 * GuC inaccessible range. We resort to perma-pinning an additional vma 1207 * within the accessible range that only contains the RSA signature. 1208 * The GuC HW can use this extra pinning to perform the authentication 1209 * since its GGTT offset will be GuC accessible. 1210 */ 1211 GEM_BUG_ON(uc_fw->rsa_size > PAGE_SIZE); 1212 vma = intel_guc_allocate_vma(>->uc.guc, PAGE_SIZE); 1213 if (IS_ERR(vma)) 1214 return PTR_ERR(vma); 1215 1216 vaddr = i915_gem_object_pin_map_unlocked(vma->obj, 1217 intel_gt_coherent_map_type(gt, vma->obj, true)); 1218 if (IS_ERR(vaddr)) { 1219 i915_vma_unpin_and_release(&vma, 0); 1220 err = PTR_ERR(vaddr); 1221 goto unpin_out; 1222 } 1223 1224 copied = intel_uc_fw_copy_rsa(uc_fw, vaddr, vma->size); 1225 i915_gem_object_unpin_map(vma->obj); 1226 1227 if (copied < uc_fw->rsa_size) { 1228 err = -ENOMEM; 1229 goto unpin_out; 1230 } 1231 1232 uc_fw->rsa_data = vma; 1233 1234 return 0; 1235 1236 unpin_out: 1237 i915_vma_unpin_and_release(&vma, 0); 1238 return err; 1239 } 1240 1241 static void uc_fw_rsa_data_destroy(struct intel_uc_fw *uc_fw) 1242 { 1243 i915_vma_unpin_and_release(&uc_fw->rsa_data, 0); 1244 } 1245 1246 int intel_uc_fw_init(struct intel_uc_fw *uc_fw) 1247 { 1248 int err; 1249 1250 /* this should happen before the load! */ 1251 GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw)); 1252 1253 if (!intel_uc_fw_is_available(uc_fw)) 1254 return -ENOEXEC; 1255 1256 err = i915_gem_object_pin_pages_unlocked(uc_fw->obj); 1257 if (err) { 1258 gt_dbg(__uc_fw_to_gt(uc_fw), "%s fw pin-pages failed %pe\n", 1259 intel_uc_fw_type_repr(uc_fw->type), ERR_PTR(err)); 1260 goto out; 1261 } 1262 1263 err = uc_fw_rsa_data_create(uc_fw); 1264 if (err) { 1265 gt_dbg(__uc_fw_to_gt(uc_fw), "%s fw rsa data creation failed %pe\n", 1266 intel_uc_fw_type_repr(uc_fw->type), ERR_PTR(err)); 1267 goto out_unpin; 1268 } 1269 1270 uc_fw_bind_ggtt(uc_fw); 1271 1272 return 0; 1273 1274 out_unpin: 1275 i915_gem_object_unpin_pages(uc_fw->obj); 1276 out: 1277 return err; 1278 } 1279 1280 void intel_uc_fw_fini(struct intel_uc_fw *uc_fw) 1281 { 1282 uc_fw_unbind_ggtt(uc_fw); 1283 uc_fw_rsa_data_destroy(uc_fw); 1284 1285 if (i915_gem_object_has_pinned_pages(uc_fw->obj)) 1286 i915_gem_object_unpin_pages(uc_fw->obj); 1287 1288 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE); 1289 } 1290 1291 void intel_uc_fw_resume_mapping(struct intel_uc_fw *uc_fw) 1292 { 1293 if (!intel_uc_fw_is_available(uc_fw)) 1294 return; 1295 1296 if (!i915_gem_object_has_pinned_pages(uc_fw->obj)) 1297 return; 1298 1299 uc_fw_bind_ggtt(uc_fw); 1300 } 1301 1302 /** 1303 * intel_uc_fw_cleanup_fetch - cleanup uC firmware 1304 * @uc_fw: uC firmware 1305 * 1306 * Cleans up uC firmware by releasing the firmware GEM obj. 1307 */ 1308 void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw) 1309 { 1310 if (!intel_uc_fw_is_available(uc_fw)) 1311 return; 1312 1313 i915_gem_object_put(fetch_and_zero(&uc_fw->obj)); 1314 1315 intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_SELECTED); 1316 } 1317 1318 /** 1319 * intel_uc_fw_copy_rsa - copy fw RSA to buffer 1320 * 1321 * @uc_fw: uC firmware 1322 * @dst: dst buffer 1323 * @max_len: max number of bytes to copy 1324 * 1325 * Return: number of copied bytes. 1326 */ 1327 size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len) 1328 { 1329 struct intel_memory_region *mr = uc_fw->obj->mm.region; 1330 u32 size = min_t(u32, uc_fw->rsa_size, max_len); 1331 u32 offset = uc_fw->dma_start_offset + sizeof(struct uc_css_header) + uc_fw->ucode_size; 1332 struct sgt_iter iter; 1333 size_t count = 0; 1334 int idx; 1335 1336 /* Called during reset handling, must be atomic [no fs_reclaim] */ 1337 GEM_BUG_ON(!intel_uc_fw_is_available(uc_fw)); 1338 1339 idx = offset >> PAGE_SHIFT; 1340 offset = offset_in_page(offset); 1341 if (i915_gem_object_has_struct_page(uc_fw->obj)) { 1342 struct page *page; 1343 1344 for_each_sgt_page(page, iter, uc_fw->obj->mm.pages) { 1345 u32 len = min_t(u32, size, PAGE_SIZE - offset); 1346 void *vaddr; 1347 1348 if (idx > 0) { 1349 idx--; 1350 continue; 1351 } 1352 1353 vaddr = kmap_atomic(page); 1354 memcpy(dst, vaddr + offset, len); 1355 kunmap_atomic(vaddr); 1356 1357 offset = 0; 1358 dst += len; 1359 size -= len; 1360 count += len; 1361 if (!size) 1362 break; 1363 } 1364 } else { 1365 dma_addr_t addr; 1366 1367 for_each_sgt_daddr(addr, iter, uc_fw->obj->mm.pages) { 1368 u32 len = min_t(u32, size, PAGE_SIZE - offset); 1369 void __iomem *vaddr; 1370 1371 if (idx > 0) { 1372 idx--; 1373 continue; 1374 } 1375 1376 vaddr = io_mapping_map_atomic_wc(&mr->iomap, 1377 addr - mr->region.start); 1378 memcpy_fromio(dst, vaddr + offset, len); 1379 io_mapping_unmap_atomic(vaddr); 1380 1381 offset = 0; 1382 dst += len; 1383 size -= len; 1384 count += len; 1385 if (!size) 1386 break; 1387 } 1388 } 1389 1390 return count; 1391 } 1392 1393 /** 1394 * intel_uc_fw_dump - dump information about uC firmware 1395 * @uc_fw: uC firmware 1396 * @p: the &drm_printer 1397 * 1398 * Pretty printer for uC firmware. 1399 */ 1400 void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p) 1401 { 1402 bool got_wanted; 1403 1404 drm_printf(p, "%s firmware: %s\n", 1405 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path); 1406 if (uc_fw->file_selected.path != uc_fw->file_wanted.path) 1407 drm_printf(p, "%s firmware wanted: %s\n", 1408 intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_wanted.path); 1409 drm_printf(p, "\tstatus: %s\n", 1410 intel_uc_fw_status_repr(uc_fw->status)); 1411 1412 if (uc_fw->file_selected.ver.major < uc_fw->file_wanted.ver.major) 1413 got_wanted = false; 1414 else if ((uc_fw->file_selected.ver.major == uc_fw->file_wanted.ver.major) && 1415 (uc_fw->file_selected.ver.minor < uc_fw->file_wanted.ver.minor)) 1416 got_wanted = false; 1417 else if ((uc_fw->file_selected.ver.major == uc_fw->file_wanted.ver.major) && 1418 (uc_fw->file_selected.ver.minor == uc_fw->file_wanted.ver.minor) && 1419 (uc_fw->file_selected.ver.patch < uc_fw->file_wanted.ver.patch)) 1420 got_wanted = false; 1421 else 1422 got_wanted = true; 1423 1424 if (!got_wanted) 1425 drm_printf(p, "\tversion: wanted %u.%u.%u, found %u.%u.%u\n", 1426 uc_fw->file_wanted.ver.major, 1427 uc_fw->file_wanted.ver.minor, 1428 uc_fw->file_wanted.ver.patch, 1429 uc_fw->file_selected.ver.major, 1430 uc_fw->file_selected.ver.minor, 1431 uc_fw->file_selected.ver.patch); 1432 else 1433 drm_printf(p, "\tversion: found %u.%u.%u\n", 1434 uc_fw->file_selected.ver.major, 1435 uc_fw->file_selected.ver.minor, 1436 uc_fw->file_selected.ver.patch); 1437 drm_printf(p, "\tuCode: %u bytes\n", uc_fw->ucode_size); 1438 drm_printf(p, "\tRSA: %u bytes\n", uc_fw->rsa_size); 1439 } 1440