90 }; |
91 }; |
91 |
92 |
92 #endif /* _SYSCALL32_IMPL */ |
93 #endif /* _SYSCALL32_IMPL */ |
93 |
94 |
94 /* |
95 /* |
95 * Microcode file information |
96 * AMD Microcode file information |
96 */ |
97 */ |
97 typedef struct ucode_header { |
98 typedef struct ucode_header_amd { |
|
99 uint32_t uh_date; |
|
100 uint32_t uh_patch_id; |
|
101 uint32_t uh_internal; /* patch data id & length, init flag */ |
|
102 uint32_t uh_cksum; |
|
103 uint32_t uh_nb_id; |
|
104 uint32_t uh_sb_id; |
|
105 uint16_t uh_cpu_rev; |
|
106 uint8_t uh_nb_rev; |
|
107 uint8_t uh_sb_rev; |
|
108 uint32_t uh_bios_rev; |
|
109 uint32_t uh_match[8]; |
|
110 } ucode_header_amd_t; |
|
111 |
|
112 typedef struct ucode_file_amd { |
|
113 ucode_header_amd_t uf_header; |
|
114 uint8_t uf_data[896]; |
|
115 uint8_t uf_resv[896]; |
|
116 uint8_t uf_code_present; |
|
117 uint8_t uf_code[191]; |
|
118 } ucode_file_amd_t; |
|
119 |
|
120 typedef struct ucode_eqtbl_amd { |
|
121 uint32_t ue_inst_cpu; |
|
122 uint32_t ue_fixed_mask; |
|
123 uint32_t ue_fixed_comp; |
|
124 uint32_t ue_equiv_cpu; |
|
125 } ucode_eqtbl_amd_t; |
|
126 |
|
127 /* |
|
128 * Intel Microcode file information |
|
129 */ |
|
130 typedef struct ucode_header_intel { |
98 uint32_t uh_header_ver; |
131 uint32_t uh_header_ver; |
99 uint32_t uh_rev; |
132 uint32_t uh_rev; |
100 uint32_t uh_date; |
133 uint32_t uh_date; |
101 uint32_t uh_signature; |
134 uint32_t uh_signature; |
102 uint32_t uh_checksum; |
135 uint32_t uh_checksum; |
103 uint32_t uh_loader_ver; |
136 uint32_t uh_loader_ver; |
104 uint32_t uh_proc_flags; |
137 uint32_t uh_proc_flags; |
105 uint32_t uh_body_size; |
138 uint32_t uh_body_size; |
106 uint32_t uh_total_size; |
139 uint32_t uh_total_size; |
107 uint32_t uh_reserved[3]; |
140 uint32_t uh_reserved[3]; |
108 } ucode_header_t; |
141 } ucode_header_intel_t; |
109 |
142 |
110 typedef struct ucode_ext_sig { |
143 typedef struct ucode_ext_sig_intel { |
111 uint32_t ues_signature; |
144 uint32_t ues_signature; |
112 uint32_t ues_proc_flags; |
145 uint32_t ues_proc_flags; |
113 uint32_t ues_checksum; |
146 uint32_t ues_checksum; |
114 } ucode_ext_sig_t; |
147 } ucode_ext_sig_intel_t; |
115 |
148 |
116 typedef struct ucode_ext_table { |
149 typedef struct ucode_ext_table_intel { |
117 uint32_t uet_count; |
150 uint32_t uet_count; |
118 uint32_t uet_checksum; |
151 uint32_t uet_checksum; |
119 uint32_t uet_reserved[3]; |
152 uint32_t uet_reserved[3]; |
120 ucode_ext_sig_t uet_ext_sig[1]; |
153 ucode_ext_sig_intel_t uet_ext_sig[1]; |
121 } ucode_ext_table_t; |
154 } ucode_ext_table_intel_t; |
122 |
155 |
123 typedef struct ucode_file { |
156 typedef struct ucode_file_intel { |
124 ucode_header_t uf_header; |
157 ucode_header_intel_t *uf_header; |
125 uint8_t *uf_body; |
158 uint8_t *uf_body; |
126 ucode_ext_table_t *uf_ext_table; |
159 ucode_ext_table_intel_t *uf_ext_table; |
|
160 } ucode_file_intel_t; |
|
161 |
|
162 /* |
|
163 * common container |
|
164 */ |
|
165 typedef union ucode_file { |
|
166 ucode_file_amd_t *amd; |
|
167 ucode_file_intel_t intel; |
127 } ucode_file_t; |
168 } ucode_file_t; |
128 |
169 |
129 |
170 |
130 #define UCODE_SHORT_NAME_LEN 12 /* "32-bit-sig"-"8-bit-platid"\0 */ |
171 #define UCODE_SHORT_NAME_LEN 12 /* "32-bit-sig"-"8-bit-platid"\0 */ |
131 /* |
172 /* |
137 #define UCODE_COMMON_NAME_LEN \ |
178 #define UCODE_COMMON_NAME_LEN \ |
138 (sizeof (UCODE_INSTALL_COMMON_PATH) + (UCODE_SHORT_NAME_LEN)) |
179 (sizeof (UCODE_INSTALL_COMMON_PATH) + (UCODE_SHORT_NAME_LEN)) |
139 #define UCODE_MAX_PATH_LEN (PATH_MAX - UCODE_COMMON_NAME_LEN) |
180 #define UCODE_MAX_PATH_LEN (PATH_MAX - UCODE_COMMON_NAME_LEN) |
140 |
181 |
141 |
182 |
142 #define UCODE_HEADER_SIZE (sizeof (struct ucode_header)) |
183 #define UCODE_HEADER_SIZE_INTEL (sizeof (struct ucode_header_intel)) |
143 #define UCODE_EXT_TABLE_SIZE (20) /* 20-bytes */ |
184 #define UCODE_EXT_TABLE_SIZE_INTEL (20) /* 20-bytes */ |
144 #define UCODE_EXT_SIG_SIZE (sizeof (struct ucode_ext_sig)) |
185 #define UCODE_EXT_SIG_SIZE_INTEL (sizeof (struct ucode_ext_sig_intel)) |
145 |
186 |
146 #define UCODE_KB(a) ((a) << 10) /* KB */ |
187 #define UCODE_KB(a) ((a) << 10) /* KB */ |
147 #define UCODE_MB(a) ((a) << 20) /* MB */ |
188 #define UCODE_MB(a) ((a) << 20) /* MB */ |
148 #define UCODE_DEFAULT_TOTAL_SIZE UCODE_KB(2) |
189 #define UCODE_DEFAULT_TOTAL_SIZE UCODE_KB(2) |
149 #define UCODE_DEFAULT_BODY_SIZE (UCODE_KB(2) - UCODE_HEADER_SIZE) |
190 #define UCODE_DEFAULT_BODY_SIZE (UCODE_KB(2) - UCODE_HEADER_SIZE_INTEL) |
150 |
191 |
151 /* |
192 /* |
152 * For a single microcode file, the minimum size is 1K, maximum size is 16K. |
193 * For a single microcode file, the minimum size is 1K, maximum size is 16K. |
153 * Such limitations, while somewhat artificial, are not only to provide better |
194 * Such limitations, while somewhat artificial, are not only to provide better |
154 * sanity checks, but also avoid wasting precious memory at startup time as the |
195 * sanity checks, but also avoid wasting precious memory at startup time as the |
162 #define UCODE_MAX_COMBINED_SIZE UCODE_MB(16) |
203 #define UCODE_MAX_COMBINED_SIZE UCODE_MB(16) |
163 |
204 |
164 #define UCODE_SIZE_CONVERT(size, default_size) \ |
205 #define UCODE_SIZE_CONVERT(size, default_size) \ |
165 ((size) == 0 ? (default_size) : (size)) |
206 ((size) == 0 ? (default_size) : (size)) |
166 |
207 |
167 #define UCODE_BODY_SIZE(size) \ |
208 #define UCODE_BODY_SIZE_INTEL(size) \ |
168 UCODE_SIZE_CONVERT((size), UCODE_DEFAULT_BODY_SIZE) |
209 UCODE_SIZE_CONVERT((size), UCODE_DEFAULT_BODY_SIZE) |
169 |
210 |
170 #define UCODE_TOTAL_SIZE(size) \ |
211 #define UCODE_TOTAL_SIZE_INTEL(size) \ |
171 UCODE_SIZE_CONVERT((size), UCODE_DEFAULT_TOTAL_SIZE) |
212 UCODE_SIZE_CONVERT((size), UCODE_DEFAULT_TOTAL_SIZE) |
172 |
213 |
173 #define UCODE_MATCH(sig1, sig2, pf1, pf2) \ |
214 #define UCODE_MATCH_INTEL(sig1, sig2, pf1, pf2) \ |
174 (((sig1) == (sig2)) && \ |
215 (((sig1) == (sig2)) && \ |
175 (((pf1) & (pf2)) || (((pf1) == 0) && ((pf2) == 0)))) |
216 (((pf1) & (pf2)) || (((pf1) == 0) && ((pf2) == 0)))) |
176 |
217 |
177 extern ucode_errno_t ucode_header_validate(ucode_header_t *); |
218 extern ucode_errno_t ucode_header_validate_intel(ucode_header_intel_t *); |
178 extern uint32_t ucode_checksum(uint32_t, uint32_t, uint8_t *); |
219 extern uint32_t ucode_checksum_intel(uint32_t, uint32_t, uint8_t *); |
179 extern ucode_errno_t ucode_validate(uint8_t *, int); |
220 |
|
221 extern ucode_errno_t ucode_validate_amd(uint8_t *, int); |
|
222 extern ucode_errno_t ucode_validate_intel(uint8_t *, int); |
|
223 |
|
224 #ifdef _KERNEL |
180 extern ucode_errno_t ucode_get_rev(uint32_t *); |
225 extern ucode_errno_t ucode_get_rev(uint32_t *); |
181 extern ucode_errno_t ucode_update(uint8_t *, int); |
226 extern ucode_errno_t ucode_update(uint8_t *, int); |
|
227 |
|
228 /* |
|
229 * Microcode specific information per core |
|
230 */ |
|
231 typedef struct cpu_ucode_info { |
|
232 uint32_t cui_platid; /* platform id */ |
|
233 uint32_t cui_rev; /* microcode revision */ |
|
234 } cpu_ucode_info_t; |
|
235 |
|
236 /* |
|
237 * Data structure used for xcall |
|
238 */ |
|
239 typedef struct ucode_update { |
|
240 uint32_t sig; /* signature */ |
|
241 cpu_ucode_info_t info; /* ucode info */ |
|
242 uint32_t expected_rev; |
|
243 uint32_t new_rev; |
|
244 uint8_t *ucodep; /* pointer to ucode */ |
|
245 uint32_t usize; |
|
246 } ucode_update_t; |
|
247 |
|
248 /* |
|
249 * Microcode kernel operations |
|
250 */ |
|
251 struct ucode_ops { |
|
252 uint32_t write_msr; |
|
253 int (*capable)(cpu_t *); |
|
254 void (*file_reset)(ucode_file_t *, processorid_t); |
|
255 void (*read_rev)(cpu_ucode_info_t *); |
|
256 uint32_t (*load)(ucode_file_t *, cpu_ucode_info_t *, cpu_t *); |
|
257 ucode_errno_t (*validate)(uint8_t *, int); |
|
258 ucode_errno_t (*extract)(ucode_update_t *, uint8_t *, int); |
|
259 ucode_errno_t (*locate)(cpu_t *, cpu_ucode_info_t *, ucode_file_t *); |
|
260 }; |
|
261 #else |
182 |
262 |
183 #define UCODE_MAX_VENDORS_NAME_LEN 20 |
263 #define UCODE_MAX_VENDORS_NAME_LEN 20 |
184 |
264 |
185 #define UCODE_VENDORS \ |
265 #define UCODE_VENDORS \ |
186 static struct { \ |
266 static struct { \ |
187 char *filestr; \ |
267 char *filestr; \ |
|
268 char *extstr; \ |
188 char *vendorstr; \ |
269 char *vendorstr; \ |
189 int supported; \ |
270 int supported; \ |
190 } ucode_vendors[] = { \ |
271 } ucode_vendors[] = { \ |
191 { "intel", "GenuineIntel", 1 }, \ |
272 { "intel", "txt", "GenuineIntel", 1 }, \ |
192 { "amd", "AuthenticAMD", 0 }, \ |
273 { "amd", "bin", "AuthenticAMD", 1 }, \ |
193 { NULL, NULL, 0 } \ |
274 { NULL, NULL, NULL, 0 } \ |
194 } |
275 } |
|
276 |
|
277 /* |
|
278 * Microcode user operations |
|
279 */ |
|
280 struct ucode_ops { |
|
281 int (*convert)(const char *, uint8_t *, size_t); |
|
282 ucode_errno_t (*gen_files)(uint8_t *, int, char *); |
|
283 ucode_errno_t (*validate)(uint8_t *, int); |
|
284 }; |
|
285 #endif |
|
286 |
|
287 extern const struct ucode_ops *ucode; |
195 |
288 |
196 #ifdef __cplusplus |
289 #ifdef __cplusplus |
197 } |
290 } |
198 #endif |
291 #endif |
199 |
292 |