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