File: | dev/pci/drm/i915/gt/uc/intel_uc_fw.c |
Warning: | line 423, column 27 Value stored to 'i915' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 "intel_uc_fw.h" |
15 | #include "intel_uc_fw_abi.h" |
16 | #include "i915_drv.h" |
17 | #include "i915_reg.h" |
18 | |
19 | static inline struct intel_gt * |
20 | ____uc_fw_to_gt(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type) |
21 | { |
22 | if (type == INTEL_UC_FW_TYPE_GUC) |
23 | return container_of(uc_fw, struct intel_gt, uc.guc.fw)({ const __typeof( ((struct intel_gt *)0)->uc.guc.fw ) *__mptr = (uc_fw); (struct intel_gt *)( (char *)__mptr - __builtin_offsetof (struct intel_gt, uc.guc.fw) );}); |
24 | |
25 | GEM_BUG_ON(type != INTEL_UC_FW_TYPE_HUC)((void)0); |
26 | return container_of(uc_fw, struct intel_gt, uc.huc.fw)({ const __typeof( ((struct intel_gt *)0)->uc.huc.fw ) *__mptr = (uc_fw); (struct intel_gt *)( (char *)__mptr - __builtin_offsetof (struct intel_gt, uc.huc.fw) );}); |
27 | } |
28 | |
29 | static inline struct intel_gt *__uc_fw_to_gt(struct intel_uc_fw *uc_fw) |
30 | { |
31 | GEM_BUG_ON(uc_fw->status == INTEL_UC_FIRMWARE_UNINITIALIZED)((void)0); |
32 | return ____uc_fw_to_gt(uc_fw, uc_fw->type); |
33 | } |
34 | |
35 | #ifdef CONFIG_DRM_I915_DEBUG_GUC |
36 | void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw, |
37 | enum intel_uc_fw_status status) |
38 | { |
39 | uc_fw->__status = status; |
40 | drm_dbg(&__uc_fw_to_gt(uc_fw)->i915->drm,__drm_dev_dbg(((void *)0), (&__uc_fw_to_gt(uc_fw)->i915 ->drm) ? (&__uc_fw_to_gt(uc_fw)->i915->drm)-> dev : ((void *)0), DRM_UT_DRIVER, "%s firmware -> %s\n", intel_uc_fw_type_repr (uc_fw->type), status == INTEL_UC_FIRMWARE_SELECTED ? uc_fw ->file_selected.path : intel_uc_fw_status_repr(status)) |
41 | "%s firmware -> %s\n",__drm_dev_dbg(((void *)0), (&__uc_fw_to_gt(uc_fw)->i915 ->drm) ? (&__uc_fw_to_gt(uc_fw)->i915->drm)-> dev : ((void *)0), DRM_UT_DRIVER, "%s firmware -> %s\n", intel_uc_fw_type_repr (uc_fw->type), status == INTEL_UC_FIRMWARE_SELECTED ? uc_fw ->file_selected.path : intel_uc_fw_status_repr(status)) |
42 | intel_uc_fw_type_repr(uc_fw->type),__drm_dev_dbg(((void *)0), (&__uc_fw_to_gt(uc_fw)->i915 ->drm) ? (&__uc_fw_to_gt(uc_fw)->i915->drm)-> dev : ((void *)0), DRM_UT_DRIVER, "%s firmware -> %s\n", intel_uc_fw_type_repr (uc_fw->type), status == INTEL_UC_FIRMWARE_SELECTED ? uc_fw ->file_selected.path : intel_uc_fw_status_repr(status)) |
43 | status == INTEL_UC_FIRMWARE_SELECTED ?__drm_dev_dbg(((void *)0), (&__uc_fw_to_gt(uc_fw)->i915 ->drm) ? (&__uc_fw_to_gt(uc_fw)->i915->drm)-> dev : ((void *)0), DRM_UT_DRIVER, "%s firmware -> %s\n", intel_uc_fw_type_repr (uc_fw->type), status == INTEL_UC_FIRMWARE_SELECTED ? uc_fw ->file_selected.path : intel_uc_fw_status_repr(status)) |
44 | uc_fw->file_selected.path : intel_uc_fw_status_repr(status))__drm_dev_dbg(((void *)0), (&__uc_fw_to_gt(uc_fw)->i915 ->drm) ? (&__uc_fw_to_gt(uc_fw)->i915->drm)-> dev : ((void *)0), DRM_UT_DRIVER, "%s firmware -> %s\n", intel_uc_fw_type_repr (uc_fw->type), status == INTEL_UC_FIRMWARE_SELECTED ? uc_fw ->file_selected.path : intel_uc_fw_status_repr(status)); |
45 | } |
46 | #endif |
47 | |
48 | /* |
49 | * List of required GuC and HuC binaries per-platform. |
50 | * Must be ordered based on platform + revid, from newer to older. |
51 | * |
52 | * Note that RKL and ADL-S have the same GuC/HuC device ID's and use the same |
53 | * firmware as TGL. |
54 | * |
55 | * Version numbers: |
56 | * Originally, the driver required an exact match major/minor/patch furmware |
57 | * file and only supported that one version for any given platform. However, |
58 | * the new direction from upstream is to be backwards compatible with all |
59 | * prior releases and to be as flexible as possible as to what firmware is |
60 | * loaded. |
61 | * |
62 | * For GuC, the major version number signifies a backwards breaking API change. |
63 | * So, new format GuC firmware files are labelled by their major version only. |
64 | * For HuC, there is no KMD interaction, hence no version matching requirement. |
65 | * So, new format HuC firmware files have no version number at all. |
66 | * |
67 | * All of which means that the table below must keep all old format files with |
68 | * full three point version number. But newer files have reduced requirements. |
69 | * Having said that, the driver still needs to track the minor version number |
70 | * for GuC at least. As it is useful to report to the user that they are not |
71 | * running with a recent enough version for all KMD supported features, |
72 | * security fixes, etc. to be enabled. |
73 | */ |
74 | #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp)fw_def(DG2, 0, guc_maj(dg2, 70, 5)) fw_def(ALDERLAKE_P, 0, guc_maj (adlp, 70, 5)) fw_def(ALDERLAKE_P, 0, guc_mmp(adlp, 70, 1, 1) ) fw_def(ALDERLAKE_P, 0, guc_mmp(adlp, 69, 0, 3)) fw_def(ALDERLAKE_S , 0, guc_maj(tgl, 70, 5)) fw_def(ALDERLAKE_S, 0, guc_mmp(tgl, 70, 1, 1)) fw_def(ALDERLAKE_S, 0, guc_mmp(tgl, 69, 0, 3)) fw_def (DG1, 0, guc_maj(dg1, 70, 5)) fw_def(ROCKETLAKE, 0, guc_mmp(tgl , 70, 1, 1)) fw_def(TIGERLAKE, 0, guc_mmp(tgl, 70, 1, 1)) fw_def (JASPERLAKE, 0, guc_mmp(ehl, 70, 1, 1)) fw_def(ELKHARTLAKE, 0 , guc_mmp(ehl, 70, 1, 1)) fw_def(ICELAKE, 0, guc_mmp(icl, 70, 1, 1)) fw_def(COMETLAKE, 5, guc_mmp(cml, 70, 1, 1)) fw_def(COMETLAKE , 0, guc_mmp(kbl, 70, 1, 1)) fw_def(COFFEELAKE, 0, guc_mmp(kbl , 70, 1, 1)) fw_def(GEMINILAKE, 0, guc_mmp(glk, 70, 1, 1)) fw_def (KABYLAKE, 0, guc_mmp(kbl, 70, 1, 1)) fw_def(BROXTON, 0, guc_mmp (bxt, 70, 1, 1)) fw_def(SKYLAKE, 0, guc_mmp(skl, 70, 1, 1)) \ |
75 | fw_def(DG2, 0, guc_maj(dg2, 70, 5)) \ |
76 | fw_def(ALDERLAKE_P, 0, guc_maj(adlp, 70, 5)) \ |
77 | fw_def(ALDERLAKE_P, 0, guc_mmp(adlp, 70, 1, 1)) \ |
78 | fw_def(ALDERLAKE_P, 0, guc_mmp(adlp, 69, 0, 3)) \ |
79 | fw_def(ALDERLAKE_S, 0, guc_maj(tgl, 70, 5)) \ |
80 | fw_def(ALDERLAKE_S, 0, guc_mmp(tgl, 70, 1, 1)) \ |
81 | fw_def(ALDERLAKE_S, 0, guc_mmp(tgl, 69, 0, 3)) \ |
82 | fw_def(DG1, 0, guc_maj(dg1, 70, 5)) \ |
83 | fw_def(ROCKETLAKE, 0, guc_mmp(tgl, 70, 1, 1)) \ |
84 | fw_def(TIGERLAKE, 0, guc_mmp(tgl, 70, 1, 1)) \ |
85 | fw_def(JASPERLAKE, 0, guc_mmp(ehl, 70, 1, 1)) \ |
86 | fw_def(ELKHARTLAKE, 0, guc_mmp(ehl, 70, 1, 1)) \ |
87 | fw_def(ICELAKE, 0, guc_mmp(icl, 70, 1, 1)) \ |
88 | fw_def(COMETLAKE, 5, guc_mmp(cml, 70, 1, 1)) \ |
89 | fw_def(COMETLAKE, 0, guc_mmp(kbl, 70, 1, 1)) \ |
90 | fw_def(COFFEELAKE, 0, guc_mmp(kbl, 70, 1, 1)) \ |
91 | fw_def(GEMINILAKE, 0, guc_mmp(glk, 70, 1, 1)) \ |
92 | fw_def(KABYLAKE, 0, guc_mmp(kbl, 70, 1, 1)) \ |
93 | fw_def(BROXTON, 0, guc_mmp(bxt, 70, 1, 1)) \ |
94 | fw_def(SKYLAKE, 0, guc_mmp(skl, 70, 1, 1)) |
95 | |
96 | #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_raw, huc_mmp)fw_def(ALDERLAKE_P, 0, huc_raw(tgl)) fw_def(ALDERLAKE_P, 0, huc_mmp (tgl, 7, 9, 3)) fw_def(ALDERLAKE_S, 0, huc_raw(tgl)) fw_def(ALDERLAKE_S , 0, huc_mmp(tgl, 7, 9, 3)) fw_def(DG1, 0, huc_raw(dg1)) fw_def (ROCKETLAKE, 0, huc_mmp(tgl, 7, 9, 3)) fw_def(TIGERLAKE, 0, huc_mmp (tgl, 7, 9, 3)) fw_def(JASPERLAKE, 0, huc_mmp(ehl, 9, 0, 0)) fw_def (ELKHARTLAKE, 0, huc_mmp(ehl, 9, 0, 0)) fw_def(ICELAKE, 0, huc_mmp (icl, 9, 0, 0)) fw_def(COMETLAKE, 5, huc_mmp(cml, 4, 0, 0)) fw_def (COMETLAKE, 0, huc_mmp(kbl, 4, 0, 0)) fw_def(COFFEELAKE, 0, huc_mmp (kbl, 4, 0, 0)) fw_def(GEMINILAKE, 0, huc_mmp(glk, 4, 0, 0)) fw_def (KABYLAKE, 0, huc_mmp(kbl, 4, 0, 0)) fw_def(BROXTON, 0, huc_mmp (bxt, 2, 0, 0)) fw_def(SKYLAKE, 0, huc_mmp(skl, 2, 0, 0)) \ |
97 | fw_def(ALDERLAKE_P, 0, huc_raw(tgl)) \ |
98 | fw_def(ALDERLAKE_P, 0, huc_mmp(tgl, 7, 9, 3)) \ |
99 | fw_def(ALDERLAKE_S, 0, huc_raw(tgl)) \ |
100 | fw_def(ALDERLAKE_S, 0, huc_mmp(tgl, 7, 9, 3)) \ |
101 | fw_def(DG1, 0, huc_raw(dg1)) \ |
102 | fw_def(ROCKETLAKE, 0, huc_mmp(tgl, 7, 9, 3)) \ |
103 | fw_def(TIGERLAKE, 0, huc_mmp(tgl, 7, 9, 3)) \ |
104 | fw_def(JASPERLAKE, 0, huc_mmp(ehl, 9, 0, 0)) \ |
105 | fw_def(ELKHARTLAKE, 0, huc_mmp(ehl, 9, 0, 0)) \ |
106 | fw_def(ICELAKE, 0, huc_mmp(icl, 9, 0, 0)) \ |
107 | fw_def(COMETLAKE, 5, huc_mmp(cml, 4, 0, 0)) \ |
108 | fw_def(COMETLAKE, 0, huc_mmp(kbl, 4, 0, 0)) \ |
109 | fw_def(COFFEELAKE, 0, huc_mmp(kbl, 4, 0, 0)) \ |
110 | fw_def(GEMINILAKE, 0, huc_mmp(glk, 4, 0, 0)) \ |
111 | fw_def(KABYLAKE, 0, huc_mmp(kbl, 4, 0, 0)) \ |
112 | fw_def(BROXTON, 0, huc_mmp(bxt, 2, 0, 0)) \ |
113 | fw_def(SKYLAKE, 0, huc_mmp(skl, 2, 0, 0)) |
114 | |
115 | /* |
116 | * Set of macros for producing a list of filenames from the above table. |
117 | */ |
118 | #define __MAKE_UC_FW_PATH_BLANK(prefix_, name_)"i915/" "prefix_" name_ ".bin" \ |
119 | "i915/" \ |
120 | __stringify(prefix_)"prefix_" name_ ".bin" |
121 | |
122 | #define __MAKE_UC_FW_PATH_MAJOR(prefix_, name_, major_)"i915/" "prefix_" name_ "major_" ".bin" \ |
123 | "i915/" \ |
124 | __stringify(prefix_)"prefix_" name_ \ |
125 | __stringify(major_)"major_" ".bin" |
126 | |
127 | #define __MAKE_UC_FW_PATH_MMP(prefix_, name_, major_, minor_, patch_)"i915/" "prefix_" name_ "major_" "." "minor_" "." "patch_" ".bin" \ |
128 | "i915/" \ |
129 | __stringify(prefix_)"prefix_" name_ \ |
130 | __stringify(major_)"major_" "." \ |
131 | __stringify(minor_)"minor_" "." \ |
132 | __stringify(patch_)"patch_" ".bin" |
133 | |
134 | /* Minor for internal driver use, not part of file name */ |
135 | #define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_)"i915/" "prefix_" "_guc_" "major_" ".bin" \ |
136 | __MAKE_UC_FW_PATH_MAJOR(prefix_, "_guc_", major_)"i915/" "prefix_" "_guc_" "major_" ".bin" |
137 | |
138 | #define MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_)"i915/" "prefix_" "_guc_" "major_" "." "minor_" "." "patch_" ".bin" \ |
139 | __MAKE_UC_FW_PATH_MMP(prefix_, "_guc_", major_, minor_, patch_)"i915/" "prefix_" "_guc_" "major_" "." "minor_" "." "patch_" ".bin" |
140 | |
141 | #define MAKE_HUC_FW_PATH_BLANK(prefix_)"i915/" "prefix_" "_huc" ".bin" \ |
142 | __MAKE_UC_FW_PATH_BLANK(prefix_, "_huc")"i915/" "prefix_" "_huc" ".bin" |
143 | |
144 | #define MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_)"i915/" "prefix_" "_huc_" "major_" "." "minor_" "." "patch_" ".bin" \ |
145 | __MAKE_UC_FW_PATH_MMP(prefix_, "_huc_", major_, minor_, patch_)"i915/" "prefix_" "_huc_" "major_" "." "minor_" "." "patch_" ".bin" |
146 | |
147 | /* |
148 | * All blobs need to be declared via MODULE_FIRMWARE(). |
149 | * This first expansion of the table macros is solely to provide |
150 | * that declaration. |
151 | */ |
152 | #define INTEL_UC_MODULE_FW(platform_, revid_, uc_); \ |
153 | MODULE_FIRMWARE(uc_); |
154 | |
155 | INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH_MAJOR, MAKE_GUC_FW_PATH_MMP); ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; |
156 | INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, MAKE_HUC_FW_PATH_MMP); ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; |
157 | |
158 | /* |
159 | * The next expansion of the table macros (in __uc_fw_auto_select below) provides |
160 | * actual data structures with both the filename and the version information. |
161 | * These structure arrays are then iterated over to the list of suitable files |
162 | * for the current platform and to then attempt to load those files, in the order |
163 | * listed, until one is successfully found. |
164 | */ |
165 | struct __packed__attribute__((__packed__)) uc_fw_blob { |
166 | const char *path; |
167 | bool_Bool legacy; |
168 | u8 major; |
169 | u8 minor; |
170 | u8 patch; |
171 | }; |
172 | |
173 | #define UC_FW_BLOB_BASE(major_, minor_, patch_, path_).major = major_, .minor = minor_, .patch = patch_, .path = path_ , \ |
174 | .major = major_, \ |
175 | .minor = minor_, \ |
176 | .patch = patch_, \ |
177 | .path = path_, |
178 | |
179 | #define UC_FW_BLOB_NEW(major_, minor_, patch_, path_){ .major = major_, .minor = minor_, .patch = patch_, .path = path_ , .legacy = 0 } \ |
180 | { UC_FW_BLOB_BASE(major_, minor_, patch_, path_).major = major_, .minor = minor_, .patch = patch_, .path = path_ , \ |
181 | .legacy = false0 } |
182 | |
183 | #define UC_FW_BLOB_OLD(major_, minor_, patch_, path_){ .major = major_, .minor = minor_, .patch = patch_, .path = path_ , .legacy = 1 } \ |
184 | { UC_FW_BLOB_BASE(major_, minor_, patch_, path_).major = major_, .minor = minor_, .patch = patch_, .path = path_ , \ |
185 | .legacy = true1 } |
186 | |
187 | #define GUC_FW_BLOB(prefix_, major_, minor_){ .major = major_, .minor = minor_, .patch = 0, .path = "i915/" "prefix_" "_guc_" "major_" ".bin", .legacy = 0 } \ |
188 | UC_FW_BLOB_NEW(major_, minor_, 0, \{ .major = major_, .minor = minor_, .patch = 0, .path = "i915/" "prefix_" "_guc_" "major_" ".bin", .legacy = 0 } |
189 | MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_)){ .major = major_, .minor = minor_, .patch = 0, .path = "i915/" "prefix_" "_guc_" "major_" ".bin", .legacy = 0 } |
190 | |
191 | #define GUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_){ .major = major_, .minor = minor_, .patch = patch_, .path = "i915/" "prefix_" "_guc_" "major_" "." "minor_" "." "patch_" ".bin", .legacy = 1 } \ |
192 | UC_FW_BLOB_OLD(major_, minor_, patch_, \{ .major = major_, .minor = minor_, .patch = patch_, .path = "i915/" "prefix_" "_guc_" "major_" "." "minor_" "." "patch_" ".bin", .legacy = 1 } |
193 | MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_)){ .major = major_, .minor = minor_, .patch = patch_, .path = "i915/" "prefix_" "_guc_" "major_" "." "minor_" "." "patch_" ".bin", .legacy = 1 } |
194 | |
195 | #define HUC_FW_BLOB(prefix_){ .major = 0, .minor = 0, .patch = 0, .path = "i915/" "prefix_" "_huc" ".bin", .legacy = 0 } \ |
196 | UC_FW_BLOB_NEW(0, 0, 0, MAKE_HUC_FW_PATH_BLANK(prefix_)){ .major = 0, .minor = 0, .patch = 0, .path = "i915/" "prefix_" "_huc" ".bin", .legacy = 0 } |
197 | |
198 | #define HUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_){ .major = major_, .minor = minor_, .patch = patch_, .path = "i915/" "prefix_" "_huc_" "major_" "." "minor_" "." "patch_" ".bin", .legacy = 1 } \ |
199 | UC_FW_BLOB_OLD(major_, minor_, patch_, \{ .major = major_, .minor = minor_, .patch = patch_, .path = "i915/" "prefix_" "_huc_" "major_" "." "minor_" "." "patch_" ".bin", .legacy = 1 } |
200 | MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_)){ .major = major_, .minor = minor_, .patch = patch_, .path = "i915/" "prefix_" "_huc_" "major_" "." "minor_" "." "patch_" ".bin", .legacy = 1 } |
201 | |
202 | struct __packed__attribute__((__packed__)) uc_fw_platform_requirement { |
203 | enum intel_platform p; |
204 | u8 rev; /* first platform rev using this FW */ |
205 | const struct uc_fw_blob blob; |
206 | }; |
207 | |
208 | #define MAKE_FW_LIST(platform_, revid_, uc_){ .p = INTEL_platform_, .rev = revid_, .blob = uc_, }, \ |
209 | { \ |
210 | .p = INTEL_##platform_, \ |
211 | .rev = revid_, \ |
212 | .blob = uc_, \ |
213 | }, |
214 | |
215 | struct fw_blobs_by_type { |
216 | const struct uc_fw_platform_requirement *blobs; |
217 | u32 count; |
218 | }; |
219 | |
220 | static void |
221 | __uc_fw_auto_select(struct drm_i915_privateinteldrm_softc *i915, struct intel_uc_fw *uc_fw) |
222 | { |
223 | static const struct uc_fw_platform_requirement blobs_guc[] = { |
224 | INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, GUC_FW_BLOB_MMP){ .p = INTEL_DG2, .rev = 0, .blob = { .major = 70, .minor = 5 , .patch = 0, .path = "i915/" "dg2" "_guc_" "70" ".bin", .legacy = 0 }, }, { .p = INTEL_ALDERLAKE_P, .rev = 0, .blob = { .major = 70, .minor = 5, .patch = 0, .path = "i915/" "adlp" "_guc_" "70" ".bin", .legacy = 0 }, }, { .p = INTEL_ALDERLAKE_P, .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "adlp" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, } , { .p = INTEL_ALDERLAKE_P, .rev = 0, .blob = { .major = 69, . minor = 0, .patch = 3, .path = "i915/" "adlp" "_guc_" "69" "." "0" "." "3" ".bin", .legacy = 1 }, }, { .p = INTEL_ALDERLAKE_S , .rev = 0, .blob = { .major = 70, .minor = 5, .patch = 0, .path = "i915/" "tgl" "_guc_" "70" ".bin", .legacy = 0 }, }, { .p = INTEL_ALDERLAKE_S, .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "tgl" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_ALDERLAKE_S, .rev = 0, .blob = { .major = 69, .minor = 0, .patch = 3, .path = "i915/" "tgl" "_guc_" "69" "." "0" "." "3" ".bin", .legacy = 1 }, }, { .p = INTEL_DG1, .rev = 0, .blob = { .major = 70, .minor = 5 , .patch = 0, .path = "i915/" "dg1" "_guc_" "70" ".bin", .legacy = 0 }, }, { .p = INTEL_ROCKETLAKE, .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "tgl" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_TIGERLAKE , .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "tgl" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_JASPERLAKE, .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "ehl" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_ELKHARTLAKE , .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "ehl" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_ICELAKE, .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "icl" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_COMETLAKE , .rev = 5, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "cml" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_COMETLAKE, .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "kbl" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_COFFEELAKE , .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "kbl" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_GEMINILAKE, .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "glk" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_KABYLAKE , .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "kbl" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_BROXTON, .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "bxt" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, { .p = INTEL_SKYLAKE , .rev = 0, .blob = { .major = 70, .minor = 1, .patch = 1, .path = "i915/" "skl" "_guc_" "70" "." "1" "." "1" ".bin", .legacy = 1 }, }, |
225 | }; |
226 | static const struct uc_fw_platform_requirement blobs_huc[] = { |
227 | INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP){ .p = INTEL_ALDERLAKE_P, .rev = 0, .blob = { .major = 0, .minor = 0, .patch = 0, .path = "i915/" "tgl" "_huc" ".bin", .legacy = 0 }, }, { .p = INTEL_ALDERLAKE_P, .rev = 0, .blob = { .major = 7, .minor = 9, .patch = 3, .path = "i915/" "tgl" "_huc_" "7" "." "9" "." "3" ".bin", .legacy = 1 }, }, { .p = INTEL_ALDERLAKE_S , .rev = 0, .blob = { .major = 0, .minor = 0, .patch = 0, .path = "i915/" "tgl" "_huc" ".bin", .legacy = 0 }, }, { .p = INTEL_ALDERLAKE_S , .rev = 0, .blob = { .major = 7, .minor = 9, .patch = 3, .path = "i915/" "tgl" "_huc_" "7" "." "9" "." "3" ".bin", .legacy = 1 }, }, { .p = INTEL_DG1, .rev = 0, .blob = { .major = 0, .minor = 0, .patch = 0, .path = "i915/" "dg1" "_huc" ".bin", .legacy = 0 }, }, { .p = INTEL_ROCKETLAKE, .rev = 0, .blob = { .major = 7, .minor = 9, .patch = 3, .path = "i915/" "tgl" "_huc_" "7" "." "9" "." "3" ".bin", .legacy = 1 }, }, { .p = INTEL_TIGERLAKE , .rev = 0, .blob = { .major = 7, .minor = 9, .patch = 3, .path = "i915/" "tgl" "_huc_" "7" "." "9" "." "3" ".bin", .legacy = 1 }, }, { .p = INTEL_JASPERLAKE, .rev = 0, .blob = { .major = 9, .minor = 0, .patch = 0, .path = "i915/" "ehl" "_huc_" "9" "." "0" "." "0" ".bin", .legacy = 1 }, }, { .p = INTEL_ELKHARTLAKE , .rev = 0, .blob = { .major = 9, .minor = 0, .patch = 0, .path = "i915/" "ehl" "_huc_" "9" "." "0" "." "0" ".bin", .legacy = 1 }, }, { .p = INTEL_ICELAKE, .rev = 0, .blob = { .major = 9 , .minor = 0, .patch = 0, .path = "i915/" "icl" "_huc_" "9" "." "0" "." "0" ".bin", .legacy = 1 }, }, { .p = INTEL_COMETLAKE , .rev = 5, .blob = { .major = 4, .minor = 0, .patch = 0, .path = "i915/" "cml" "_huc_" "4" "." "0" "." "0" ".bin", .legacy = 1 }, }, { .p = INTEL_COMETLAKE, .rev = 0, .blob = { .major = 4, .minor = 0, .patch = 0, .path = "i915/" "kbl" "_huc_" "4" "." "0" "." "0" ".bin", .legacy = 1 }, }, { .p = INTEL_COFFEELAKE , .rev = 0, .blob = { .major = 4, .minor = 0, .patch = 0, .path = "i915/" "kbl" "_huc_" "4" "." "0" "." "0" ".bin", .legacy = 1 }, }, { .p = INTEL_GEMINILAKE, .rev = 0, .blob = { .major = 4, .minor = 0, .patch = 0, .path = "i915/" "glk" "_huc_" "4" "." "0" "." "0" ".bin", .legacy = 1 }, }, { .p = INTEL_KABYLAKE , .rev = 0, .blob = { .major = 4, .minor = 0, .patch = 0, .path = "i915/" "kbl" "_huc_" "4" "." "0" "." "0" ".bin", .legacy = 1 }, }, { .p = INTEL_BROXTON, .rev = 0, .blob = { .major = 2 , .minor = 0, .patch = 0, .path = "i915/" "bxt" "_huc_" "2" "." "0" "." "0" ".bin", .legacy = 1 }, }, { .p = INTEL_SKYLAKE, . rev = 0, .blob = { .major = 2, .minor = 0, .patch = 0, .path = "i915/" "skl" "_huc_" "2" "." "0" "." "0" ".bin", .legacy = 1 }, }, |
228 | }; |
229 | static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES2] = { |
230 | [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc)(sizeof((blobs_guc)) / sizeof((blobs_guc)[0])) }, |
231 | [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc)(sizeof((blobs_huc)) / sizeof((blobs_huc)[0])) }, |
232 | }; |
233 | static bool_Bool verified; |
234 | const struct uc_fw_platform_requirement *fw_blobs; |
235 | enum intel_platform p = INTEL_INFO(i915)(&(i915)->__info)->platform; |
236 | u32 fw_count; |
237 | u8 rev = INTEL_REVID(i915)((i915)->drm.pdev->revision); |
238 | int i; |
239 | bool_Bool found; |
240 | |
241 | /* |
242 | * The only difference between the ADL GuC FWs is the HWConfig support. |
243 | * ADL-N does not support HWConfig, so we should use the same binary as |
244 | * ADL-S, otherwise the GuC might attempt to fetch a config table that |
245 | * does not exist. |
246 | */ |
247 | if (IS_ADLP_N(i915)IS_SUBPLATFORM(i915, INTEL_ALDERLAKE_P, 1)) |
248 | p = INTEL_ALDERLAKE_S; |
249 | |
250 | GEM_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all))((void)0); |
251 | fw_blobs = blobs_all[uc_fw->type].blobs; |
252 | fw_count = blobs_all[uc_fw->type].count; |
253 | |
254 | found = false0; |
255 | for (i = 0; i < fw_count && p <= fw_blobs[i].p; i++) { |
256 | const struct uc_fw_blob *blob = &fw_blobs[i].blob; |
257 | |
258 | if (p != fw_blobs[i].p) |
259 | continue; |
260 | |
261 | if (rev < fw_blobs[i].rev) |
262 | continue; |
263 | |
264 | if (uc_fw->file_selected.path) { |
265 | if (uc_fw->file_selected.path == blob->path) |
266 | uc_fw->file_selected.path = NULL((void *)0); |
267 | |
268 | continue; |
269 | } |
270 | |
271 | uc_fw->file_selected.path = blob->path; |
272 | uc_fw->file_wanted.path = blob->path; |
273 | uc_fw->file_wanted.major_ver = blob->major; |
274 | uc_fw->file_wanted.minor_ver = blob->minor; |
275 | found = true1; |
276 | break; |
277 | } |
278 | |
279 | if (!found && uc_fw->file_selected.path) { |
280 | /* Failed to find a match for the last attempt?! */ |
281 | uc_fw->file_selected.path = NULL((void *)0); |
282 | } |
283 | |
284 | /* make sure the list is ordered as expected */ |
285 | if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST)0 && !verified) { |
286 | verified = true1; |
287 | |
288 | for (i = 1; i < fw_count; i++) { |
289 | /* Next platform is good: */ |
290 | if (fw_blobs[i].p < fw_blobs[i - 1].p) |
291 | continue; |
292 | |
293 | /* Next platform revision is good: */ |
294 | if (fw_blobs[i].p == fw_blobs[i - 1].p && |
295 | fw_blobs[i].rev < fw_blobs[i - 1].rev) |
296 | continue; |
297 | |
298 | /* Platform/revision must be in order: */ |
299 | if (fw_blobs[i].p != fw_blobs[i - 1].p || |
300 | fw_blobs[i].rev != fw_blobs[i - 1].rev) |
301 | goto bad; |
302 | |
303 | /* Next major version is good: */ |
304 | if (fw_blobs[i].blob.major < fw_blobs[i - 1].blob.major) |
305 | continue; |
306 | |
307 | /* New must be before legacy: */ |
308 | if (!fw_blobs[i].blob.legacy && fw_blobs[i - 1].blob.legacy) |
309 | goto bad; |
310 | |
311 | /* New to legacy also means 0.0 to X.Y (HuC), or X.0 to X.Y (GuC) */ |
312 | if (fw_blobs[i].blob.legacy && !fw_blobs[i - 1].blob.legacy) { |
313 | if (!fw_blobs[i - 1].blob.major) |
314 | continue; |
315 | |
316 | if (fw_blobs[i].blob.major == fw_blobs[i - 1].blob.major) |
317 | continue; |
318 | } |
319 | |
320 | /* Major versions must be in order: */ |
321 | if (fw_blobs[i].blob.major != fw_blobs[i - 1].blob.major) |
322 | goto bad; |
323 | |
324 | /* Next minor version is good: */ |
325 | if (fw_blobs[i].blob.minor < fw_blobs[i - 1].blob.minor) |
326 | continue; |
327 | |
328 | /* Minor versions must be in order: */ |
329 | if (fw_blobs[i].blob.minor != fw_blobs[i - 1].blob.minor) |
330 | goto bad; |
331 | |
332 | /* Patch versions must be in order: */ |
333 | if (fw_blobs[i].blob.patch <= fw_blobs[i - 1].blob.patch) |
334 | continue; |
335 | |
336 | bad: |
337 | drm_err(&i915->drm, "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch) |
338 | intel_platform_name(fw_blobs[i - 1].p), fw_blobs[i - 1].rev,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch) |
339 | fw_blobs[i - 1].blob.legacy ? "L" : "v",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch) |
340 | fw_blobs[i - 1].blob.major,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch) |
341 | fw_blobs[i - 1].blob.minor,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch) |
342 | fw_blobs[i - 1].blob.patch,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch) |
343 | intel_platform_name(fw_blobs[i].p), fw_blobs[i].rev,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch) |
344 | fw_blobs[i].blob.legacy ? "L" : "v",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch) |
345 | fw_blobs[i].blob.major,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch) |
346 | fw_blobs[i].blob.minor,printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch) |
347 | fw_blobs[i].blob.patch)printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "Invalid FW blob order: %s r%u %s%d.%d.%d comes before %s r%u %s%d.%d.%d\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_platform_name (fw_blobs[i - 1].p), fw_blobs[i - 1].rev, fw_blobs[i - 1].blob .legacy ? "L" : "v", fw_blobs[i - 1].blob.major, fw_blobs[i - 1].blob.minor, fw_blobs[i - 1].blob.patch, intel_platform_name (fw_blobs[i].p), fw_blobs[i].rev, fw_blobs[i].blob.legacy ? "L" : "v", fw_blobs[i].blob.major, fw_blobs[i].blob.minor, fw_blobs [i].blob.patch); |
348 | |
349 | uc_fw->file_selected.path = NULL((void *)0); |
350 | } |
351 | } |
352 | } |
353 | |
354 | static const char *__override_guc_firmware_path(struct drm_i915_privateinteldrm_softc *i915) |
355 | { |
356 | if (i915->params.enable_guc & ENABLE_GUC_MASK(((~0UL) >> (64 - (1) - 1)) & ((~0UL) << (0)) )) |
357 | return i915->params.guc_firmware_path; |
358 | return ""; |
359 | } |
360 | |
361 | static const char *__override_huc_firmware_path(struct drm_i915_privateinteldrm_softc *i915) |
362 | { |
363 | if (i915->params.enable_guc & ENABLE_GUC_LOAD_HUC(1UL << (1))) |
364 | return i915->params.huc_firmware_path; |
365 | return ""; |
366 | } |
367 | |
368 | static void __uc_fw_user_override(struct drm_i915_privateinteldrm_softc *i915, struct intel_uc_fw *uc_fw) |
369 | { |
370 | const char *path = NULL((void *)0); |
371 | |
372 | switch (uc_fw->type) { |
373 | case INTEL_UC_FW_TYPE_GUC: |
374 | path = __override_guc_firmware_path(i915); |
375 | break; |
376 | case INTEL_UC_FW_TYPE_HUC: |
377 | path = __override_huc_firmware_path(i915); |
378 | break; |
379 | } |
380 | |
381 | if (unlikely(path)__builtin_expect(!!(path), 0)) { |
382 | uc_fw->file_selected.path = path; |
383 | uc_fw->user_overridden = true1; |
384 | } |
385 | } |
386 | |
387 | /** |
388 | * intel_uc_fw_init_early - initialize the uC object and select the firmware |
389 | * @uc_fw: uC firmware |
390 | * @type: type of uC |
391 | * |
392 | * Initialize the state of our uC object and relevant tracking and select the |
393 | * firmware to fetch and load. |
394 | */ |
395 | void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw, |
396 | enum intel_uc_fw_type type) |
397 | { |
398 | struct drm_i915_privateinteldrm_softc *i915 = ____uc_fw_to_gt(uc_fw, type)->i915; |
399 | |
400 | /* |
401 | * we use FIRMWARE_UNINITIALIZED to detect checks against uc_fw->status |
402 | * before we're looked at the HW caps to see if we have uc support |
403 | */ |
404 | BUILD_BUG_ON(INTEL_UC_FIRMWARE_UNINITIALIZED)extern char _ctassert[(!(INTEL_UC_FIRMWARE_UNINITIALIZED)) ? 1 : -1 ] __attribute__((__unused__)); |
405 | GEM_BUG_ON(uc_fw->status)((void)0); |
406 | GEM_BUG_ON(uc_fw->file_selected.path)((void)0); |
407 | |
408 | uc_fw->type = type; |
409 | |
410 | if (HAS_GT_UC(i915)((&(i915)->__info)->has_gt_uc)) { |
411 | __uc_fw_auto_select(i915, uc_fw); |
412 | __uc_fw_user_override(i915, uc_fw); |
413 | } |
414 | |
415 | intel_uc_fw_change_status(uc_fw, uc_fw->file_selected.path ? *uc_fw->file_selected.path ? |
416 | INTEL_UC_FIRMWARE_SELECTED : |
417 | INTEL_UC_FIRMWARE_DISABLED : |
418 | INTEL_UC_FIRMWARE_NOT_SUPPORTED); |
419 | } |
420 | |
421 | static void __force_fw_fetch_failures(struct intel_uc_fw *uc_fw, int e) |
422 | { |
423 | struct drm_i915_privateinteldrm_softc *i915 = __uc_fw_to_gt(uc_fw)->i915; |
Value stored to 'i915' during its initialization is never read | |
424 | bool_Bool user = e == -EINVAL22; |
425 | |
426 | if (i915_inject_probe_error(i915, e)({ ((void)0); 0; })) { |
427 | /* non-existing blob */ |
428 | uc_fw->file_selected.path = "<invalid>"; |
429 | uc_fw->user_overridden = user; |
430 | } else if (i915_inject_probe_error(i915, e)({ ((void)0); 0; })) { |
431 | /* require next major version */ |
432 | uc_fw->file_wanted.major_ver += 1; |
433 | uc_fw->file_wanted.minor_ver = 0; |
434 | uc_fw->user_overridden = user; |
435 | } else if (i915_inject_probe_error(i915, e)({ ((void)0); 0; })) { |
436 | /* require next minor version */ |
437 | uc_fw->file_wanted.minor_ver += 1; |
438 | uc_fw->user_overridden = user; |
439 | } else if (uc_fw->file_wanted.major_ver && |
440 | i915_inject_probe_error(i915, e)({ ((void)0); 0; })) { |
441 | /* require prev major version */ |
442 | uc_fw->file_wanted.major_ver -= 1; |
443 | uc_fw->file_wanted.minor_ver = 0; |
444 | uc_fw->user_overridden = user; |
445 | } else if (uc_fw->file_wanted.minor_ver && |
446 | i915_inject_probe_error(i915, e)({ ((void)0); 0; })) { |
447 | /* require prev minor version - hey, this should work! */ |
448 | uc_fw->file_wanted.minor_ver -= 1; |
449 | uc_fw->user_overridden = user; |
450 | } else if (user && i915_inject_probe_error(i915, e)({ ((void)0); 0; })) { |
451 | /* officially unsupported platform */ |
452 | uc_fw->file_wanted.major_ver = 0; |
453 | uc_fw->file_wanted.minor_ver = 0; |
454 | uc_fw->user_overridden = true1; |
455 | } |
456 | } |
457 | |
458 | static int check_gsc_manifest(const struct firmware *fw, |
459 | struct intel_uc_fw *uc_fw) |
460 | { |
461 | u32 *dw = (u32 *)fw->data; |
462 | u32 version_hi = dw[HUC_GSC_VERSION_HI_DW44]; |
463 | u32 version_lo = dw[HUC_GSC_VERSION_LO_DW45]; |
464 | |
465 | uc_fw->file_selected.major_ver = FIELD_GET(HUC_GSC_MAJOR_VER_HI_MASK, version_hi)((typeof((0xFF << 0)))(((version_hi) & ((0xFF << 0))) >> (__builtin_ffsll((0xFF << 0)) - 1))); |
466 | uc_fw->file_selected.minor_ver = FIELD_GET(HUC_GSC_MINOR_VER_HI_MASK, version_hi)((typeof((0xFF << 16)))(((version_hi) & ((0xFF << 16))) >> (__builtin_ffsll((0xFF << 16)) - 1))); |
467 | uc_fw->file_selected.patch_ver = FIELD_GET(HUC_GSC_PATCH_VER_LO_MASK, version_lo)((typeof((0xFF << 0)))(((version_lo) & ((0xFF << 0))) >> (__builtin_ffsll((0xFF << 0)) - 1))); |
468 | |
469 | return 0; |
470 | } |
471 | |
472 | static int check_ccs_header(struct drm_i915_privateinteldrm_softc *i915, |
473 | const struct firmware *fw, |
474 | struct intel_uc_fw *uc_fw) |
475 | { |
476 | struct uc_css_header *css; |
477 | size_t size; |
478 | |
479 | /* Check the size of the blob before examining buffer contents */ |
480 | if (unlikely(fw->size < sizeof(struct uc_css_header))__builtin_expect(!!(fw->size < sizeof(struct uc_css_header )), 0)) { |
481 | drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu < %zu\n",printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: invalid size: %zu < %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, fw->size, sizeof (struct uc_css_header)) |
482 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: invalid size: %zu < %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, fw->size, sizeof (struct uc_css_header)) |
483 | fw->size, sizeof(struct uc_css_header))printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: invalid size: %zu < %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, fw->size, sizeof (struct uc_css_header)); |
484 | return -ENODATA91; |
485 | } |
486 | |
487 | css = (struct uc_css_header *)fw->data; |
488 | |
489 | /* Check integrity of size values inside CSS header */ |
490 | size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw - |
491 | css->exponent_size_dw) * sizeof(u32); |
492 | if (unlikely(size != sizeof(struct uc_css_header))__builtin_expect(!!(size != sizeof(struct uc_css_header)), 0)) { |
493 | drm_warn(&i915->drm,printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: unexpected header size: %zu != %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, fw->size, sizeof (struct uc_css_header)) |
494 | "%s firmware %s: unexpected header size: %zu != %zu\n",printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: unexpected header size: %zu != %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, fw->size, sizeof (struct uc_css_header)) |
495 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: unexpected header size: %zu != %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, fw->size, sizeof (struct uc_css_header)) |
496 | fw->size, sizeof(struct uc_css_header))printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: unexpected header size: %zu != %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, fw->size, sizeof (struct uc_css_header)); |
497 | return -EPROTO95; |
498 | } |
499 | |
500 | /* uCode size must calculated from other sizes */ |
501 | uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32); |
502 | |
503 | /* now RSA */ |
504 | uc_fw->rsa_size = css->key_size_dw * sizeof(u32); |
505 | |
506 | /* At least, it should have header, uCode and RSA. Size of all three. */ |
507 | size = sizeof(struct uc_css_header) + uc_fw->ucode_size + uc_fw->rsa_size; |
508 | if (unlikely(fw->size < size)__builtin_expect(!!(fw->size < size), 0)) { |
509 | drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu < %zu\n",printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: invalid size: %zu < %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, fw->size, size ) |
510 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: invalid size: %zu < %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, fw->size, size ) |
511 | fw->size, size)printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: invalid size: %zu < %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, fw->size, size ); |
512 | return -ENOEXEC8; |
513 | } |
514 | |
515 | /* Sanity check whether this fw is not larger than whole WOPCM memory */ |
516 | size = __intel_uc_fw_get_upload_size(uc_fw); |
517 | if (unlikely(size >= i915->wopcm.size)__builtin_expect(!!(size >= i915->wopcm.size), 0)) { |
518 | drm_warn(&i915->drm, "%s firmware %s: invalid size: %zu > %zu\n",printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: invalid size: %zu > %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, size, (size_t )i915->wopcm.size) |
519 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: invalid size: %zu > %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, size, (size_t )i915->wopcm.size) |
520 | size, (size_t)i915->wopcm.size)printf("drm:pid%d:%s *WARNING* " "[drm] " "%s firmware %s: invalid size: %zu > %zu\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, size, (size_t )i915->wopcm.size); |
521 | return -E2BIG7; |
522 | } |
523 | |
524 | /* Get version numbers from the CSS header */ |
525 | uc_fw->file_selected.major_ver = FIELD_GET(CSS_SW_VERSION_UC_MAJOR,((typeof((0xFF << 16)))(((css->sw_version) & ((0xFF << 16))) >> (__builtin_ffsll((0xFF << 16)) - 1))) |
526 | css->sw_version)((typeof((0xFF << 16)))(((css->sw_version) & ((0xFF << 16))) >> (__builtin_ffsll((0xFF << 16)) - 1))); |
527 | uc_fw->file_selected.minor_ver = FIELD_GET(CSS_SW_VERSION_UC_MINOR,((typeof((0xFF << 8)))(((css->sw_version) & ((0xFF << 8))) >> (__builtin_ffsll((0xFF << 8)) - 1))) |
528 | css->sw_version)((typeof((0xFF << 8)))(((css->sw_version) & ((0xFF << 8))) >> (__builtin_ffsll((0xFF << 8)) - 1))); |
529 | uc_fw->file_selected.patch_ver = FIELD_GET(CSS_SW_VERSION_UC_PATCH,((typeof((0xFF << 0)))(((css->sw_version) & ((0xFF << 0))) >> (__builtin_ffsll((0xFF << 0)) - 1))) |
530 | css->sw_version)((typeof((0xFF << 0)))(((css->sw_version) & ((0xFF << 0))) >> (__builtin_ffsll((0xFF << 0)) - 1))); |
531 | |
532 | if (uc_fw->type == INTEL_UC_FW_TYPE_GUC) |
533 | uc_fw->private_data_size = css->private_data_size; |
534 | |
535 | return 0; |
536 | } |
537 | |
538 | /** |
539 | * intel_uc_fw_fetch - fetch uC firmware |
540 | * @uc_fw: uC firmware |
541 | * |
542 | * Fetch uC firmware into GEM obj. |
543 | * |
544 | * Return: 0 on success, a negative errno code on failure. |
545 | */ |
546 | int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw) |
547 | { |
548 | struct drm_i915_privateinteldrm_softc *i915 = __uc_fw_to_gt(uc_fw)->i915; |
549 | struct intel_uc_fw_file file_ideal; |
550 | struct device *dev = i915->drm.dev; |
551 | struct drm_i915_gem_object *obj; |
552 | const struct firmware *fw = NULL((void *)0); |
553 | bool_Bool old_ver = false0; |
554 | int err; |
555 | |
556 | GEM_BUG_ON(!i915->wopcm.size)((void)0); |
557 | GEM_BUG_ON(!intel_uc_fw_is_enabled(uc_fw))((void)0); |
558 | |
559 | err = i915_inject_probe_error(i915, -ENXIO)({ ((void)0); 0; }); |
560 | if (err) |
561 | goto fail; |
562 | |
563 | __force_fw_fetch_failures(uc_fw, -EINVAL22); |
564 | __force_fw_fetch_failures(uc_fw, -ESTALE70); |
565 | |
566 | err = firmware_request_nowarn(&fw, uc_fw->file_selected.path, dev); |
567 | memcpy(&file_ideal, &uc_fw->file_wanted, sizeof(file_ideal))__builtin_memcpy((&file_ideal), (&uc_fw->file_wanted ), (sizeof(file_ideal))); |
568 | |
569 | /* Any error is terminal if overriding. Don't bother searching for older versions */ |
570 | if (err && intel_uc_fw_is_overridden(uc_fw)) |
571 | goto fail; |
572 | |
573 | while (err == -ENOENT2) { |
574 | old_ver = true1; |
575 | |
576 | __uc_fw_auto_select(i915, uc_fw); |
577 | if (!uc_fw->file_selected.path) { |
578 | /* |
579 | * No more options! But set the path back to something |
580 | * valid just in case it gets dereferenced. |
581 | */ |
582 | uc_fw->file_selected.path = file_ideal.path; |
583 | |
584 | /* Also, preserve the version that was really wanted */ |
585 | memcpy(&uc_fw->file_wanted, &file_ideal, sizeof(uc_fw->file_wanted))__builtin_memcpy((&uc_fw->file_wanted), (&file_ideal ), (sizeof(uc_fw->file_wanted))); |
586 | break; |
587 | } |
588 | |
589 | err = firmware_request_nowarn(&fw, uc_fw->file_selected.path, dev); |
590 | } |
591 | |
592 | if (err) |
593 | goto fail; |
594 | |
595 | if (uc_fw->loaded_via_gsc) |
596 | err = check_gsc_manifest(fw, uc_fw); |
597 | else |
598 | err = check_ccs_header(i915, fw, uc_fw); |
599 | if (err) |
600 | goto fail; |
601 | |
602 | if (uc_fw->file_wanted.major_ver) { |
603 | /* Check the file's major version was as it claimed */ |
604 | if (uc_fw->file_selected.major_ver != uc_fw->file_wanted.major_ver) { |
605 | drm_notice(&i915->drm, "%s firmware %s: unexpected version: %u.%u != %u.%u\n",printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s: unexpected version: %u.%u != %u.%u\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, uc_fw->file_selected .major_ver, uc_fw->file_selected.minor_ver, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver) |
606 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s: unexpected version: %u.%u != %u.%u\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, uc_fw->file_selected .major_ver, uc_fw->file_selected.minor_ver, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver) |
607 | uc_fw->file_selected.major_ver, uc_fw->file_selected.minor_ver,printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s: unexpected version: %u.%u != %u.%u\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, uc_fw->file_selected .major_ver, uc_fw->file_selected.minor_ver, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver) |
608 | uc_fw->file_wanted.major_ver, uc_fw->file_wanted.minor_ver)printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s: unexpected version: %u.%u != %u.%u\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_selected.path, uc_fw->file_selected .major_ver, uc_fw->file_selected.minor_ver, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver); |
609 | if (!intel_uc_fw_is_overridden(uc_fw)) { |
610 | err = -ENOEXEC8; |
611 | goto fail; |
612 | } |
613 | } else { |
614 | if (uc_fw->file_selected.minor_ver < uc_fw->file_wanted.minor_ver) |
615 | old_ver = true1; |
616 | } |
617 | } |
618 | |
619 | if (old_ver) { |
620 | /* Preserve the version that was really wanted */ |
621 | memcpy(&uc_fw->file_wanted, &file_ideal, sizeof(uc_fw->file_wanted))__builtin_memcpy((&uc_fw->file_wanted), (&file_ideal ), (sizeof(uc_fw->file_wanted))); |
622 | |
623 | drm_notice(&i915->drm,printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_wanted.path, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver, uc_fw->file_selected .path, uc_fw->file_selected.major_ver, uc_fw->file_selected .minor_ver) |
624 | "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n",printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_wanted.path, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver, uc_fw->file_selected .path, uc_fw->file_selected.major_ver, uc_fw->file_selected .minor_ver) |
625 | intel_uc_fw_type_repr(uc_fw->type),printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_wanted.path, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver, uc_fw->file_selected .path, uc_fw->file_selected.major_ver, uc_fw->file_selected .minor_ver) |
626 | uc_fw->file_wanted.path,printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_wanted.path, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver, uc_fw->file_selected .path, uc_fw->file_selected.major_ver, uc_fw->file_selected .minor_ver) |
627 | uc_fw->file_wanted.major_ver, uc_fw->file_wanted.minor_ver,printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_wanted.path, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver, uc_fw->file_selected .path, uc_fw->file_selected.major_ver, uc_fw->file_selected .minor_ver) |
628 | uc_fw->file_selected.path,printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_wanted.path, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver, uc_fw->file_selected .path, uc_fw->file_selected.major_ver, uc_fw->file_selected .minor_ver) |
629 | uc_fw->file_selected.major_ver, uc_fw->file_selected.minor_ver)printf("drm:pid%d:%s *NOTICE* " "[drm] " "%s firmware %s (%d.%d) is recommended, but only %s (%d.%d) was found\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), uc_fw->file_wanted.path, uc_fw->file_wanted .major_ver, uc_fw->file_wanted.minor_ver, uc_fw->file_selected .path, uc_fw->file_selected.major_ver, uc_fw->file_selected .minor_ver); |
630 | drm_info(&i915->drm,do { } while(0) |
631 | "Consider updating your linux-firmware pkg or downloading from %s\n",do { } while(0) |
632 | INTEL_UC_FIRMWARE_URL)do { } while(0); |
633 | } |
634 | |
635 | if (HAS_LMEM(i915)((&(i915)->__runtime)->memory_regions & ((1UL << (INTEL_REGION_LMEM_0))))) { |
636 | obj = i915_gem_object_create_lmem_from_data(i915, fw->data, fw->size); |
637 | if (!IS_ERR(obj)) |
638 | obj->flags |= I915_BO_ALLOC_PM_EARLY(1UL << (5)); |
639 | } else { |
640 | obj = i915_gem_object_create_shmem_from_data(i915, fw->data, fw->size); |
641 | } |
642 | |
643 | if (IS_ERR(obj)) { |
644 | err = PTR_ERR(obj); |
645 | goto fail; |
646 | } |
647 | |
648 | uc_fw->obj = obj; |
649 | uc_fw->size = fw->size; |
650 | intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE); |
651 | |
652 | release_firmware(fw); |
653 | return 0; |
654 | |
655 | fail: |
656 | intel_uc_fw_change_status(uc_fw, err == -ENOENT2 ? |
657 | INTEL_UC_FIRMWARE_MISSING : |
658 | INTEL_UC_FIRMWARE_ERROR); |
659 | |
660 | i915_probe_error(i915, "%s firmware %s: fetch failed with error %d\n",__i915_printk(i915, 0 ? "\0017" : "\0013", "%s firmware %s: fetch failed with error %d\n" , intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected .path, err) |
661 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path, err)__i915_printk(i915, 0 ? "\0017" : "\0013", "%s firmware %s: fetch failed with error %d\n" , intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected .path, err); |
662 | #ifdef __linux__ |
663 | drm_info(&i915->drm, "%s firmware(s) can be downloaded from %s\n",do { } while(0) |
664 | intel_uc_fw_type_repr(uc_fw->type), INTEL_UC_FIRMWARE_URL)do { } while(0); |
665 | #endif |
666 | |
667 | release_firmware(fw); /* OK even if fw is NULL */ |
668 | return err; |
669 | } |
670 | |
671 | static u32 uc_fw_ggtt_offset(struct intel_uc_fw *uc_fw) |
672 | { |
673 | struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt; |
674 | struct drm_mm_node *node = &ggtt->uc_fw; |
675 | |
676 | GEM_BUG_ON(!drm_mm_node_allocated(node))((void)0); |
677 | GEM_BUG_ON(upper_32_bits(node->start))((void)0); |
678 | GEM_BUG_ON(upper_32_bits(node->start + node->size - 1))((void)0); |
679 | |
680 | return lower_32_bits(node->start)((u32)(node->start)); |
681 | } |
682 | |
683 | static void uc_fw_bind_ggtt(struct intel_uc_fw *uc_fw) |
684 | { |
685 | struct drm_i915_gem_object *obj = uc_fw->obj; |
686 | struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt; |
687 | struct i915_vma_resource *dummy = &uc_fw->dummy; |
688 | u32 pte_flags = 0; |
689 | |
690 | dummy->start = uc_fw_ggtt_offset(uc_fw); |
691 | dummy->node_size = obj->base.size; |
692 | dummy->bi.pages = obj->mm.pages; |
693 | |
694 | GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj))((void)0); |
695 | GEM_BUG_ON(dummy->node_size > ggtt->uc_fw.size)((void)0); |
696 | |
697 | /* uc_fw->obj cache domains were not controlled across suspend */ |
698 | if (i915_gem_object_has_struct_page(obj)) |
699 | drm_clflush_sg(dummy->bi.pages); |
700 | |
701 | if (i915_gem_object_is_lmem(obj)) |
702 | pte_flags |= PTE_LM(1UL << (1)); |
703 | |
704 | if (ggtt->vm.raw_insert_entries) |
705 | ggtt->vm.raw_insert_entries(&ggtt->vm, dummy, I915_CACHE_NONE, pte_flags); |
706 | else |
707 | ggtt->vm.insert_entries(&ggtt->vm, dummy, I915_CACHE_NONE, pte_flags); |
708 | } |
709 | |
710 | static void uc_fw_unbind_ggtt(struct intel_uc_fw *uc_fw) |
711 | { |
712 | struct drm_i915_gem_object *obj = uc_fw->obj; |
713 | struct i915_ggtt *ggtt = __uc_fw_to_gt(uc_fw)->ggtt; |
714 | u64 start = uc_fw_ggtt_offset(uc_fw); |
715 | |
716 | ggtt->vm.clear_range(&ggtt->vm, start, obj->base.size); |
717 | } |
718 | |
719 | static int uc_fw_xfer(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags) |
720 | { |
721 | struct intel_gt *gt = __uc_fw_to_gt(uc_fw); |
722 | struct intel_uncore *uncore = gt->uncore; |
723 | u64 offset; |
724 | int ret; |
725 | |
726 | ret = i915_inject_probe_error(gt->i915, -ETIMEDOUT)({ ((void)0); 0; }); |
727 | if (ret) |
728 | return ret; |
729 | |
730 | intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); |
731 | |
732 | /* Set the source address for the uCode */ |
733 | offset = uc_fw_ggtt_offset(uc_fw); |
734 | GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000)((void)0); |
735 | intel_uncore_write_fw(uncore, DMA_ADDR_0_LOW, lower_32_bits(offset))__raw_uncore_write32(uncore, ((const i915_reg_t){ .reg = (0xc300 ) }), ((u32)(offset))); |
736 | intel_uncore_write_fw(uncore, DMA_ADDR_0_HIGH, upper_32_bits(offset))__raw_uncore_write32(uncore, ((const i915_reg_t){ .reg = (0xc304 ) }), ((u32)(((offset) >> 16) >> 16))); |
737 | |
738 | /* Set the DMA destination */ |
739 | intel_uncore_write_fw(uncore, DMA_ADDR_1_LOW, dst_offset)__raw_uncore_write32(uncore, ((const i915_reg_t){ .reg = (0xc308 ) }), dst_offset); |
740 | intel_uncore_write_fw(uncore, DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM)__raw_uncore_write32(uncore, ((const i915_reg_t){ .reg = (0xc30c ) }), (7 << 16)); |
741 | |
742 | /* |
743 | * Set the transfer size. The header plus uCode will be copied to WOPCM |
744 | * via DMA, excluding any other components |
745 | */ |
746 | intel_uncore_write_fw(uncore, DMA_COPY_SIZE,__raw_uncore_write32(uncore, ((const i915_reg_t){ .reg = (0xc310 ) }), sizeof(struct uc_css_header) + uc_fw->ucode_size) |
747 | sizeof(struct uc_css_header) + uc_fw->ucode_size)__raw_uncore_write32(uncore, ((const i915_reg_t){ .reg = (0xc310 ) }), sizeof(struct uc_css_header) + uc_fw->ucode_size); |
748 | |
749 | /* Start the DMA */ |
750 | intel_uncore_write_fw(uncore, DMA_CTRL,__raw_uncore_write32(uncore, ((const i915_reg_t){ .reg = (0xc314 ) }), ({ typeof(dma_flags | (1<<0)) _a = (dma_flags | ( 1<<0)); ({ if (__builtin_constant_p(_a)) do { } while ( 0); if (__builtin_constant_p(_a)) do { } while (0); if (__builtin_constant_p (_a) && __builtin_constant_p(_a)) do { } while (0); ( (_a) << 16 | (_a)); }); })) |
751 | _MASKED_BIT_ENABLE(dma_flags | START_DMA))__raw_uncore_write32(uncore, ((const i915_reg_t){ .reg = (0xc314 ) }), ({ typeof(dma_flags | (1<<0)) _a = (dma_flags | ( 1<<0)); ({ if (__builtin_constant_p(_a)) do { } while ( 0); if (__builtin_constant_p(_a)) do { } while (0); if (__builtin_constant_p (_a) && __builtin_constant_p(_a)) do { } while (0); ( (_a) << 16 | (_a)); }); })); |
752 | |
753 | /* Wait for DMA to finish */ |
754 | ret = intel_wait_for_register_fw(uncore, DMA_CTRL((const i915_reg_t){ .reg = (0xc314) }), START_DMA(1<<0), 0, 100); |
755 | if (ret) |
756 | drm_err(>->i915->drm, "DMA for %s fw failed, DMA_CTRL=%u\n",printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DMA for %s fw failed, DMA_CTRL=%u\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), __raw_uncore_read32(uncore, ((const i915_reg_t ){ .reg = (0xc314) }))) |
757 | intel_uc_fw_type_repr(uc_fw->type),printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DMA for %s fw failed, DMA_CTRL=%u\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), __raw_uncore_read32(uncore, ((const i915_reg_t ){ .reg = (0xc314) }))) |
758 | intel_uncore_read_fw(uncore, DMA_CTRL))printf("drm:pid%d:%s *ERROR* " "[drm] " "*ERROR* " "DMA for %s fw failed, DMA_CTRL=%u\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , intel_uc_fw_type_repr (uc_fw->type), __raw_uncore_read32(uncore, ((const i915_reg_t ){ .reg = (0xc314) }))); |
759 | |
760 | /* Disable the bits once DMA is over */ |
761 | intel_uncore_write_fw(uncore, DMA_CTRL, _MASKED_BIT_DISABLE(dma_flags))__raw_uncore_write32(uncore, ((const i915_reg_t){ .reg = (0xc314 ) }), (({ if (__builtin_constant_p((dma_flags))) do { } while (0); if (__builtin_constant_p(0)) do { } while (0); if (__builtin_constant_p ((dma_flags)) && __builtin_constant_p(0)) do { } while (0); (((dma_flags)) << 16 | (0)); }))); |
762 | |
763 | intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL); |
764 | |
765 | return ret; |
766 | } |
767 | |
768 | /** |
769 | * intel_uc_fw_upload - load uC firmware using custom loader |
770 | * @uc_fw: uC firmware |
771 | * @dst_offset: destination offset |
772 | * @dma_flags: flags for flags for dma ctrl |
773 | * |
774 | * Loads uC firmware and updates internal flags. |
775 | * |
776 | * Return: 0 on success, non-zero on failure. |
777 | */ |
778 | int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 dst_offset, u32 dma_flags) |
779 | { |
780 | struct intel_gt *gt = __uc_fw_to_gt(uc_fw); |
781 | int err; |
782 | |
783 | /* make sure the status was cleared the last time we reset the uc */ |
784 | GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw))((void)0); |
785 | |
786 | err = i915_inject_probe_error(gt->i915, -ENOEXEC)({ ((void)0); 0; }); |
787 | if (err) |
788 | return err; |
789 | |
790 | if (!intel_uc_fw_is_loadable(uc_fw)) |
791 | return -ENOEXEC8; |
792 | |
793 | /* Call custom loader */ |
794 | uc_fw_bind_ggtt(uc_fw); |
795 | err = uc_fw_xfer(uc_fw, dst_offset, dma_flags); |
796 | uc_fw_unbind_ggtt(uc_fw); |
797 | if (err) |
798 | goto fail; |
799 | |
800 | intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_TRANSFERRED); |
801 | return 0; |
802 | |
803 | fail: |
804 | i915_probe_error(gt->i915, "Failed to load %s firmware %s (%d)\n",__i915_printk(gt->i915, 0 ? "\0017" : "\0013", "Failed to load %s firmware %s (%d)\n" , intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected .path, err) |
805 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,__i915_printk(gt->i915, 0 ? "\0017" : "\0013", "Failed to load %s firmware %s (%d)\n" , intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected .path, err) |
806 | err)__i915_printk(gt->i915, 0 ? "\0017" : "\0013", "Failed to load %s firmware %s (%d)\n" , intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected .path, err); |
807 | intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_LOAD_FAIL); |
808 | return err; |
809 | } |
810 | |
811 | static inline bool_Bool uc_fw_need_rsa_in_memory(struct intel_uc_fw *uc_fw) |
812 | { |
813 | /* |
814 | * The HW reads the GuC RSA from memory if the key size is > 256 bytes, |
815 | * while it reads it from the 64 RSA registers if it is smaller. |
816 | * The HuC RSA is always read from memory. |
817 | */ |
818 | return uc_fw->type == INTEL_UC_FW_TYPE_HUC || uc_fw->rsa_size > 256; |
819 | } |
820 | |
821 | static int uc_fw_rsa_data_create(struct intel_uc_fw *uc_fw) |
822 | { |
823 | struct intel_gt *gt = __uc_fw_to_gt(uc_fw); |
824 | struct i915_vma *vma; |
825 | size_t copied; |
826 | void *vaddr; |
827 | int err; |
828 | |
829 | err = i915_inject_probe_error(gt->i915, -ENXIO)({ ((void)0); 0; }); |
830 | if (err) |
831 | return err; |
832 | |
833 | if (!uc_fw_need_rsa_in_memory(uc_fw)) |
834 | return 0; |
835 | |
836 | /* |
837 | * uC firmwares will sit above GUC_GGTT_TOP and will not map through |
838 | * GGTT. Unfortunately, this means that the GuC HW cannot perform the uC |
839 | * authentication from memory, as the RSA offset now falls within the |
840 | * GuC inaccessible range. We resort to perma-pinning an additional vma |
841 | * within the accessible range that only contains the RSA signature. |
842 | * The GuC HW can use this extra pinning to perform the authentication |
843 | * since its GGTT offset will be GuC accessible. |
844 | */ |
845 | GEM_BUG_ON(uc_fw->rsa_size > PAGE_SIZE)((void)0); |
846 | vma = intel_guc_allocate_vma(>->uc.guc, PAGE_SIZE(1 << 12)); |
847 | if (IS_ERR(vma)) |
848 | return PTR_ERR(vma); |
849 | |
850 | vaddr = i915_gem_object_pin_map_unlocked(vma->obj, |
851 | i915_coherent_map_type(gt->i915, vma->obj, true1)); |
852 | if (IS_ERR(vaddr)) { |
853 | i915_vma_unpin_and_release(&vma, 0); |
854 | err = PTR_ERR(vaddr); |
855 | goto unpin_out; |
856 | } |
857 | |
858 | copied = intel_uc_fw_copy_rsa(uc_fw, vaddr, vma->size); |
859 | i915_gem_object_unpin_map(vma->obj); |
860 | |
861 | if (copied < uc_fw->rsa_size) { |
862 | err = -ENOMEM12; |
863 | goto unpin_out; |
864 | } |
865 | |
866 | uc_fw->rsa_data = vma; |
867 | |
868 | return 0; |
869 | |
870 | unpin_out: |
871 | i915_vma_unpin_and_release(&vma, 0); |
872 | return err; |
873 | } |
874 | |
875 | static void uc_fw_rsa_data_destroy(struct intel_uc_fw *uc_fw) |
876 | { |
877 | i915_vma_unpin_and_release(&uc_fw->rsa_data, 0); |
878 | } |
879 | |
880 | int intel_uc_fw_init(struct intel_uc_fw *uc_fw) |
881 | { |
882 | int err; |
883 | |
884 | /* this should happen before the load! */ |
885 | GEM_BUG_ON(intel_uc_fw_is_loaded(uc_fw))((void)0); |
886 | |
887 | if (!intel_uc_fw_is_available(uc_fw)) |
888 | return -ENOEXEC8; |
889 | |
890 | err = i915_gem_object_pin_pages_unlocked(uc_fw->obj); |
891 | if (err) { |
892 | DRM_DEBUG_DRIVER("%s fw pin-pages err=%d\n",___drm_dbg(((void *)0), DRM_UT_DRIVER, "%s fw pin-pages err=%d\n" , intel_uc_fw_type_repr(uc_fw->type), err) |
893 | intel_uc_fw_type_repr(uc_fw->type), err)___drm_dbg(((void *)0), DRM_UT_DRIVER, "%s fw pin-pages err=%d\n" , intel_uc_fw_type_repr(uc_fw->type), err); |
894 | goto out; |
895 | } |
896 | |
897 | err = uc_fw_rsa_data_create(uc_fw); |
898 | if (err) { |
899 | DRM_DEBUG_DRIVER("%s fw rsa data creation failed, err=%d\n",___drm_dbg(((void *)0), DRM_UT_DRIVER, "%s fw rsa data creation failed, err=%d\n" , intel_uc_fw_type_repr(uc_fw->type), err) |
900 | intel_uc_fw_type_repr(uc_fw->type), err)___drm_dbg(((void *)0), DRM_UT_DRIVER, "%s fw rsa data creation failed, err=%d\n" , intel_uc_fw_type_repr(uc_fw->type), err); |
901 | goto out_unpin; |
902 | } |
903 | |
904 | return 0; |
905 | |
906 | out_unpin: |
907 | i915_gem_object_unpin_pages(uc_fw->obj); |
908 | out: |
909 | intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_INIT_FAIL); |
910 | return err; |
911 | } |
912 | |
913 | void intel_uc_fw_fini(struct intel_uc_fw *uc_fw) |
914 | { |
915 | uc_fw_rsa_data_destroy(uc_fw); |
916 | |
917 | if (i915_gem_object_has_pinned_pages(uc_fw->obj)) |
918 | i915_gem_object_unpin_pages(uc_fw->obj); |
919 | |
920 | intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE); |
921 | } |
922 | |
923 | /** |
924 | * intel_uc_fw_cleanup_fetch - cleanup uC firmware |
925 | * @uc_fw: uC firmware |
926 | * |
927 | * Cleans up uC firmware by releasing the firmware GEM obj. |
928 | */ |
929 | void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw) |
930 | { |
931 | if (!intel_uc_fw_is_available(uc_fw)) |
932 | return; |
933 | |
934 | i915_gem_object_put(fetch_and_zero(&uc_fw->obj)({ typeof(*&uc_fw->obj) __T = *(&uc_fw->obj); * (&uc_fw->obj) = (typeof(*&uc_fw->obj))0; __T; } )); |
935 | |
936 | intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_SELECTED); |
937 | } |
938 | |
939 | /** |
940 | * intel_uc_fw_copy_rsa - copy fw RSA to buffer |
941 | * |
942 | * @uc_fw: uC firmware |
943 | * @dst: dst buffer |
944 | * @max_len: max number of bytes to copy |
945 | * |
946 | * Return: number of copied bytes. |
947 | */ |
948 | size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len) |
949 | { |
950 | STUB()do { printf("%s: stub\n", __func__); } while(0); |
951 | return 0; |
952 | #ifdef notyet |
953 | struct intel_memory_region *mr = uc_fw->obj->mm.region; |
954 | u32 size = min_t(u32, uc_fw->rsa_size, max_len)({ u32 __min_a = (uc_fw->rsa_size); u32 __min_b = (max_len ); __min_a < __min_b ? __min_a : __min_b; }); |
955 | u32 offset = sizeof(struct uc_css_header) + uc_fw->ucode_size; |
956 | struct sgt_iter iter; |
957 | size_t count = 0; |
958 | int idx; |
959 | |
960 | /* Called during reset handling, must be atomic [no fs_reclaim] */ |
961 | GEM_BUG_ON(!intel_uc_fw_is_available(uc_fw))((void)0); |
962 | |
963 | idx = offset >> PAGE_SHIFT12; |
964 | offset = offset_in_page(offset)((vaddr_t)(offset) & ((1 << 12) - 1)); |
965 | if (i915_gem_object_has_struct_page(uc_fw->obj)) { |
966 | struct page *page; |
967 | |
968 | for_each_sgt_page(page, iter, uc_fw->obj->mm.pages)for ((iter) = __sgt_iter((uc_fw->obj->mm.pages)->sgl , 0); ((page) = (iter).pfn == 0 ? ((void *)0) : (PHYS_TO_VM_PAGE (((paddr_t)((iter).pfn + ((iter).curr >> 12)) << 12 )))); (((iter).curr += (1 << 12)) >= (iter).max) ? ( iter) = __sgt_iter(__sg_next((iter).sgp), 0), 0 : 0) { |
969 | u32 len = min_t(u32, size, PAGE_SIZE - offset)({ u32 __min_a = (size); u32 __min_b = ((1 << 12) - offset ); __min_a < __min_b ? __min_a : __min_b; }); |
970 | void *vaddr; |
971 | |
972 | if (idx > 0) { |
973 | idx--; |
974 | continue; |
975 | } |
976 | |
977 | vaddr = kmap_atomic(page); |
978 | memcpy(dst, vaddr + offset, len)__builtin_memcpy((dst), (vaddr + offset), (len)); |
979 | kunmap_atomic(vaddr); |
980 | |
981 | offset = 0; |
982 | dst += len; |
983 | size -= len; |
984 | count += len; |
985 | if (!size) |
986 | break; |
987 | } |
988 | } else { |
989 | dma_addr_t addr; |
990 | |
991 | for_each_sgt_daddr(addr, iter, uc_fw->obj->mm.pages)for ((iter) = __sgt_iter((uc_fw->obj->mm.pages)->sgl , 1); ((addr) = (iter).dma + (iter).curr), (iter).sgp; (((iter ).curr += ((1ULL << (12)))) >= (iter).max) ? (iter) = __sgt_iter(__sg_next((iter).sgp), 1), 0 : 0) { |
992 | u32 len = min_t(u32, size, PAGE_SIZE - offset)({ u32 __min_a = (size); u32 __min_b = ((1 << 12) - offset ); __min_a < __min_b ? __min_a : __min_b; }); |
993 | void __iomem *vaddr; |
994 | |
995 | if (idx > 0) { |
996 | idx--; |
997 | continue; |
998 | } |
999 | |
1000 | vaddr = io_mapping_map_atomic_wc(&mr->iomap, |
1001 | addr - mr->region.start); |
1002 | memcpy_fromio(dst, vaddr + offset, len)__builtin_memcpy((dst), (vaddr + offset), (len)); |
1003 | io_mapping_unmap_atomic(vaddr); |
1004 | |
1005 | offset = 0; |
1006 | dst += len; |
1007 | size -= len; |
1008 | count += len; |
1009 | if (!size) |
1010 | break; |
1011 | } |
1012 | } |
1013 | |
1014 | return count; |
1015 | #endif |
1016 | } |
1017 | |
1018 | /** |
1019 | * intel_uc_fw_dump - dump information about uC firmware |
1020 | * @uc_fw: uC firmware |
1021 | * @p: the &drm_printer |
1022 | * |
1023 | * Pretty printer for uC firmware. |
1024 | */ |
1025 | void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p) |
1026 | { |
1027 | u32 ver_sel, ver_want; |
1028 | |
1029 | drm_printf(p, "%s firmware: %s\n", |
1030 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path); |
1031 | if (uc_fw->file_selected.path != uc_fw->file_wanted.path) |
1032 | drm_printf(p, "%s firmware wanted: %s\n", |
1033 | intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_wanted.path); |
1034 | drm_printf(p, "\tstatus: %s\n", |
1035 | intel_uc_fw_status_repr(uc_fw->status)); |
1036 | ver_sel = MAKE_UC_VER(uc_fw->file_selected.major_ver,((uc_fw->file_selected.patch_ver) | ((uc_fw->file_selected .minor_ver) << 8) | ((uc_fw->file_selected.major_ver ) << 16)) |
1037 | uc_fw->file_selected.minor_ver,((uc_fw->file_selected.patch_ver) | ((uc_fw->file_selected .minor_ver) << 8) | ((uc_fw->file_selected.major_ver ) << 16)) |
1038 | uc_fw->file_selected.patch_ver)((uc_fw->file_selected.patch_ver) | ((uc_fw->file_selected .minor_ver) << 8) | ((uc_fw->file_selected.major_ver ) << 16)); |
1039 | ver_want = MAKE_UC_VER(uc_fw->file_wanted.major_ver,((uc_fw->file_wanted.patch_ver) | ((uc_fw->file_wanted. minor_ver) << 8) | ((uc_fw->file_wanted.major_ver) << 16)) |
1040 | uc_fw->file_wanted.minor_ver,((uc_fw->file_wanted.patch_ver) | ((uc_fw->file_wanted. minor_ver) << 8) | ((uc_fw->file_wanted.major_ver) << 16)) |
1041 | uc_fw->file_wanted.patch_ver)((uc_fw->file_wanted.patch_ver) | ((uc_fw->file_wanted. minor_ver) << 8) | ((uc_fw->file_wanted.major_ver) << 16)); |
1042 | if (ver_sel < ver_want) |
1043 | drm_printf(p, "\tversion: wanted %u.%u.%u, found %u.%u.%u\n", |
1044 | uc_fw->file_wanted.major_ver, |
1045 | uc_fw->file_wanted.minor_ver, |
1046 | uc_fw->file_wanted.patch_ver, |
1047 | uc_fw->file_selected.major_ver, |
1048 | uc_fw->file_selected.minor_ver, |
1049 | uc_fw->file_selected.patch_ver); |
1050 | else |
1051 | drm_printf(p, "\tversion: found %u.%u.%u\n", |
1052 | uc_fw->file_selected.major_ver, |
1053 | uc_fw->file_selected.minor_ver, |
1054 | uc_fw->file_selected.patch_ver); |
1055 | drm_printf(p, "\tuCode: %u bytes\n", uc_fw->ucode_size); |
1056 | drm_printf(p, "\tRSA: %u bytes\n", uc_fw->rsa_size); |
1057 | } |