blob: a798d380a3d9c5e8475b44737cbe1ddf43e1a720 [file] [log] [blame]
AKASHI Takahirof27c2012020-11-30 18:12:12 +09001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * EFI Firmware management protocol
4 *
5 * Copyright (c) 2020 Linaro Limited
6 * Author: AKASHI Takahiro
7 */
8
9#include <common.h>
10#include <charset.h>
11#include <dfu.h>
12#include <efi_loader.h>
Masahisa Kojimabfaa1fb2023-06-07 14:41:52 +090013#include <efi_variable.h>
Sughosh Ganu86794052022-10-21 18:16:03 +053014#include <fwu.h>
AKASHI Takahirof27c2012020-11-30 18:12:12 +090015#include <image.h>
Sughosh Ganu675b62e2020-12-30 19:27:05 +053016#include <signatures.h>
17
AKASHI Takahirof27c2012020-11-30 18:12:12 +090018#include <linux/list.h>
19
Sughosh Ganu675b62e2020-12-30 19:27:05 +053020#define FMP_PAYLOAD_HDR_SIGNATURE SIGNATURE_32('M', 'S', 'S', '1')
21
22/**
23 * struct fmp_payload_header - EDK2 header for the FMP payload
24 *
25 * This structure describes the header which is preprended to the
26 * FMP payload by the edk2 capsule generation scripts.
27 *
28 * @signature: Header signature used to identify the header
29 * @header_size: Size of the structure
30 * @fw_version: Firmware versions used
31 * @lowest_supported_version: Lowest supported version
32 */
33struct fmp_payload_header {
34 u32 signature;
35 u32 header_size;
36 u32 fw_version;
37 u32 lowest_supported_version;
38};
39
Masahisa Kojimabfaa1fb2023-06-07 14:41:52 +090040/**
41 * struct fmp_state - fmp firmware update state
42 *
43 * This structure describes the state of the firmware update
44 * through FMP protocol.
45 *
46 * @fw_version: Firmware versions used
47 * @lowest_supported_version: Lowest supported version
48 * @last_attempt_version: Last attempt version
49 * @last_attempt_status: Last attempt status
50 */
51struct fmp_state {
52 u32 fw_version;
53 u32 lowest_supported_version; /* not used */
54 u32 last_attempt_version; /* not used */
55 u32 last_attempt_status; /* not used */
56};
57
Sughosh Ganua9e6f012022-04-15 11:29:37 +053058__weak void set_dfu_alt_info(char *interface, char *devstr)
59{
60 env_set("dfu_alt_info", update_info.dfu_string);
61}
62
Masahisa Kojimabfaa1fb2023-06-07 14:41:52 +090063/**
64 * efi_firmware_get_image_type_id - get image_type_id
65 * @image_index: image index
66 *
67 * Return the image_type_id identified by the image index.
68 *
69 * Return: pointer to the image_type_id, NULL if image_index is invalid
70 */
71static
72efi_guid_t *efi_firmware_get_image_type_id(u8 image_index)
73{
74 int i;
75 struct efi_fw_image *fw_array;
76
77 fw_array = update_info.images;
78 for (i = 0; i < update_info.num_images; i++) {
79 if (fw_array[i].image_index == image_index)
80 return &fw_array[i].image_type_id;
81 }
82
83 return NULL;
84}
85
AKASHI Takahirobb7e71d2020-11-17 09:28:00 +090086/* Place holder; not supported */
87static
88efi_status_t EFIAPI efi_firmware_get_image_unsupported(
89 struct efi_firmware_management_protocol *this,
90 u8 image_index,
91 void *image,
92 efi_uintn_t *image_size)
93{
94 EFI_ENTRY("%p %d %p %p\n", this, image_index, image, image_size);
95
96 return EFI_EXIT(EFI_UNSUPPORTED);
97}
98
99/* Place holder; not supported */
100static
101efi_status_t EFIAPI efi_firmware_check_image_unsupported(
102 struct efi_firmware_management_protocol *this,
103 u8 image_index,
104 const void *image,
105 efi_uintn_t *image_size,
106 u32 *image_updatable)
107{
108 EFI_ENTRY("%p %d %p %p %p\n", this, image_index, image, image_size,
109 image_updatable);
110
111 return EFI_EXIT(EFI_UNSUPPORTED);
112}
113
114/* Place holder; not supported */
115static
116efi_status_t EFIAPI efi_firmware_get_package_info_unsupported(
117 struct efi_firmware_management_protocol *this,
118 u32 *package_version,
119 u16 **package_version_name,
120 u32 *package_version_name_maxlen,
121 u64 *attributes_supported,
122 u64 *attributes_setting)
123{
124 EFI_ENTRY("%p %p %p %p %p %p\n", this, package_version,
125 package_version_name, package_version_name_maxlen,
126 attributes_supported, attributes_setting);
127
128 return EFI_EXIT(EFI_UNSUPPORTED);
129}
130
131/* Place holder; not supported */
132static
133efi_status_t EFIAPI efi_firmware_set_package_info_unsupported(
134 struct efi_firmware_management_protocol *this,
135 const void *image,
136 efi_uintn_t *image_size,
137 const void *vendor_code,
138 u32 package_version,
139 const u16 *package_version_name)
140{
141 EFI_ENTRY("%p %p %p %p %x %p\n", this, image, image_size, vendor_code,
142 package_version, package_version_name);
143
144 return EFI_EXIT(EFI_UNSUPPORTED);
145}
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900146
147/**
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530148 * efi_fill_image_desc_array - populate image descriptor array
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900149 * @image_info_size: Size of @image_info
150 * @image_info: Image information
151 * @descriptor_version: Pointer to version number
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530152 * @descriptor_count: Image count
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900153 * @descriptor_size: Pointer to descriptor size
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530154 * @package_version: Package version
155 * @package_version_name: Package version's name
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900156 *
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530157 * Return information about the current firmware image in @image_info.
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900158 * @image_info will consist of a number of descriptors.
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530159 * Each descriptor will be created based on efi_fw_image array.
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900160 *
161 * Return status code
162 */
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530163static efi_status_t efi_fill_image_desc_array(
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900164 efi_uintn_t *image_info_size,
165 struct efi_firmware_image_descriptor *image_info,
166 u32 *descriptor_version,
167 u8 *descriptor_count,
168 efi_uintn_t *descriptor_size,
169 u32 *package_version,
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530170 u16 **package_version_name)
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900171{
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530172 size_t total_size;
173 struct efi_fw_image *fw_array;
174 int i;
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900175
Masahisa Kojimacccea182023-06-07 14:41:51 +0900176 total_size = sizeof(*image_info) * update_info.num_images;
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900177
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900178 if (*image_info_size < total_size) {
179 *image_info_size = total_size;
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900180
181 return EFI_BUFFER_TOO_SMALL;
182 }
183 *image_info_size = total_size;
184
Sughosh Ganu6a463bc2022-05-31 12:45:33 +0530185 fw_array = update_info.images;
Masahisa Kojimacccea182023-06-07 14:41:51 +0900186 *descriptor_count = update_info.num_images;
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900187 *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900188 *descriptor_size = sizeof(*image_info);
189 *package_version = 0xffffffff; /* not supported */
190 *package_version_name = NULL; /* not supported */
191
Masahisa Kojimacccea182023-06-07 14:41:51 +0900192 for (i = 0; i < update_info.num_images; i++) {
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530193 image_info[i].image_index = fw_array[i].image_index;
194 image_info[i].image_type_id = fw_array[i].image_type_id;
195 image_info[i].image_id = fw_array[i].image_index;
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900196
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530197 image_info[i].image_id_name = fw_array[i].fw_name;
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900198
199 image_info[i].version = 0; /* not supported */
200 image_info[i].version_name = NULL; /* not supported */
201 image_info[i].size = 0;
202 image_info[i].attributes_supported =
Sughosh Ganu88a2ef22020-12-30 19:27:10 +0530203 IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
204 IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900205 image_info[i].attributes_setting =
206 IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
Sughosh Ganu88a2ef22020-12-30 19:27:10 +0530207
208 /* Check if the capsule authentication is enabled */
Sughosh Ganu6a2e26b2021-04-12 20:35:23 +0530209 if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE))
Sughosh Ganu88a2ef22020-12-30 19:27:10 +0530210 image_info[0].attributes_setting |=
211 IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED;
212
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900213 image_info[i].lowest_supported_image_version = 0;
214 image_info[i].last_attempt_version = 0;
215 image_info[i].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
216 image_info[i].hardware_instance = 1;
217 image_info[i].dependencies = NULL;
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900218 }
219
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900220 return EFI_SUCCESS;
221}
222
Vincent Stehlé8645aef2022-05-31 09:55:34 +0200223/**
224 * efi_firmware_capsule_authenticate - authenticate the capsule if enabled
225 * @p_image: Pointer to new image
226 * @p_image_size: Pointer to size of new image
227 *
228 * Authenticate the capsule if authentication is enabled.
229 * The image pointer and the image size are updated in case of success.
230 *
231 * Return: status code
232 */
233static
234efi_status_t efi_firmware_capsule_authenticate(const void **p_image,
235 efi_uintn_t *p_image_size)
236{
237 const void *image = *p_image;
238 efi_uintn_t image_size = *p_image_size;
Vincent Stehlé8645aef2022-05-31 09:55:34 +0200239 void *capsule_payload;
240 efi_status_t status;
241 efi_uintn_t capsule_payload_size;
242
243 if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE)) {
244 capsule_payload = NULL;
245 capsule_payload_size = 0;
246 status = efi_capsule_authenticate(image, image_size,
247 &capsule_payload,
248 &capsule_payload_size);
249
250 if (status == EFI_SECURITY_VIOLATION) {
251 printf("Capsule authentication check failed. Aborting update\n");
252 return status;
253 } else if (status != EFI_SUCCESS) {
254 return status;
255 }
256
257 debug("Capsule authentication successful\n");
258 image = capsule_payload;
259 image_size = capsule_payload_size;
260 } else {
261 debug("Capsule authentication disabled. ");
262 debug("Updating capsule without authenticating.\n");
263 }
264
Vincent Stehlé8645aef2022-05-31 09:55:34 +0200265 *p_image = image;
266 *p_image_size = image_size;
267 return EFI_SUCCESS;
268}
269
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900270/**
Masahisa Kojimabfaa1fb2023-06-07 14:41:52 +0900271 * efi_firmware_set_fmp_state_var - set FmpStateXXXX variable
272 * @state: Pointer to fmp state
273 * @image_index: image index
274 *
275 * Update the FmpStateXXXX variable with the firmware update state.
276 *
277 * Return: status code
278 */
279static
280efi_status_t efi_firmware_set_fmp_state_var(struct fmp_state *state, u8 image_index)
281{
282 u16 varname[13]; /* u"FmpStateXXXX" */
283 efi_status_t ret;
284 efi_guid_t *image_type_id;
285 struct fmp_state var_state = { 0 };
286
287 image_type_id = efi_firmware_get_image_type_id(image_index);
288 if (!image_type_id)
289 return EFI_INVALID_PARAMETER;
290
291 efi_create_indexed_name(varname, sizeof(varname), "FmpState",
292 image_index);
293
294 /*
295 * Only the fw_version is set here.
296 * lowest_supported_version in FmpState variable is ignored since
297 * it can be tampered if the file based EFI variable storage is used.
298 */
299 var_state.fw_version = state->fw_version;
300
301 ret = efi_set_variable_int(varname, image_type_id,
302 EFI_VARIABLE_READ_ONLY |
303 EFI_VARIABLE_NON_VOLATILE |
304 EFI_VARIABLE_BOOTSERVICE_ACCESS |
305 EFI_VARIABLE_RUNTIME_ACCESS,
306 sizeof(var_state), &var_state, false);
307
308 return ret;
309}
310
311/**
312 * efi_firmware_get_fw_version - get fw_version from FMP payload header
313 * @p_image: Pointer to new image
314 * @p_image_size: Pointer to size of new image
315 * @state: Pointer to fmp state
316 *
317 * Parse the FMP payload header and fill the fmp_state structure.
318 * If no FMP payload header is found, fmp_state structure is not updated.
319 *
320 */
321static void efi_firmware_get_fw_version(const void **p_image,
322 efi_uintn_t *p_image_size,
323 struct fmp_state *state)
324{
325 const struct fmp_payload_header *header;
326 u32 fmp_hdr_signature = FMP_PAYLOAD_HDR_SIGNATURE;
327
328 header = *p_image;
329 if (header->signature == fmp_hdr_signature) {
330 /* FMP header is inserted above the capsule payload */
331 state->fw_version = header->fw_version;
332
333 *p_image += header->header_size;
334 *p_image_size -= header->header_size;
335 }
336}
337
338/**
339 * efi_firmware_verify_image - verify image
340 * @p_image: Pointer to new image
341 * @p_image_size: Pointer to size of new image
342 * @image_index: Image index
343 * @state: Pointer to fmp state
344 *
345 * Verify the capsule file
346 *
347 * Return: status code
348 */
349static
350efi_status_t efi_firmware_verify_image(const void **p_image,
351 efi_uintn_t *p_image_size,
352 u8 image_index,
353 struct fmp_state *state)
354{
355 efi_status_t ret;
356
357 ret = efi_firmware_capsule_authenticate(p_image, p_image_size);
358 efi_firmware_get_fw_version(p_image, p_image_size, state);
359
360 return ret;
361}
362
363/**
Sughosh Ganu556a1262022-06-01 23:30:41 +0530364 * efi_firmware_get_image_info - return information about the current
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900365 * firmware image
366 * @this: Protocol instance
367 * @image_info_size: Size of @image_info
368 * @image_info: Image information
369 * @descriptor_version: Pointer to version number
370 * @descriptor_count: Pointer to number of descriptors
371 * @descriptor_size: Pointer to descriptor size
Vincent Stehlé7751d2e2022-05-25 11:20:22 +0200372 * @package_version: Package version
373 * @package_version_name: Package version's name
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900374 *
375 * Return information bout the current firmware image in @image_info.
376 * @image_info will consist of a number of descriptors.
377 * Each descriptor will be created based on "dfu_alt_info" variable.
378 *
379 * Return status code
380 */
381static
Sughosh Ganu556a1262022-06-01 23:30:41 +0530382efi_status_t EFIAPI efi_firmware_get_image_info(
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900383 struct efi_firmware_management_protocol *this,
384 efi_uintn_t *image_info_size,
385 struct efi_firmware_image_descriptor *image_info,
386 u32 *descriptor_version,
387 u8 *descriptor_count,
388 efi_uintn_t *descriptor_size,
389 u32 *package_version,
390 u16 **package_version_name)
391{
392 efi_status_t ret;
393
394 EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this,
395 image_info_size, image_info,
396 descriptor_version, descriptor_count, descriptor_size,
397 package_version, package_version_name);
398
399 if (!image_info_size)
400 return EFI_EXIT(EFI_INVALID_PARAMETER);
401
402 if (*image_info_size &&
403 (!image_info || !descriptor_version || !descriptor_count ||
404 !descriptor_size || !package_version || !package_version_name))
405 return EFI_EXIT(EFI_INVALID_PARAMETER);
406
Sughosh Ganu1ea06bc2022-04-15 11:29:35 +0530407 ret = efi_fill_image_desc_array(image_info_size, image_info,
408 descriptor_version, descriptor_count,
409 descriptor_size, package_version,
410 package_version_name);
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900411
412 return EFI_EXIT(ret);
413}
414
Sughosh Ganu556a1262022-06-01 23:30:41 +0530415#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_FIT
416/*
417 * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update
418 * method with existing FIT image format, and handles
419 * - multiple regions of firmware via DFU
420 * but doesn't support
421 * - versioning of firmware image
422 * - package information
423 */
424
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900425/**
426 * efi_firmware_fit_set_image - update the firmware image
427 * @this: Protocol instance
428 * @image_index: Image index number
429 * @image: New image
430 * @image_size: Size of new image
431 * @vendor_code: Vendor-specific update policy
432 * @progress: Function to report the progress of update
433 * @abort_reason: Pointer to string of abort reason
434 *
435 * Update the firmware to new image, using dfu. The new image should
436 * have FIT image format commonly used in U-Boot.
437 * @vendor_code, @progress and @abort_reason are not supported.
438 *
439 * Return: status code
440 */
441static
442efi_status_t EFIAPI efi_firmware_fit_set_image(
443 struct efi_firmware_management_protocol *this,
444 u8 image_index,
445 const void *image,
446 efi_uintn_t image_size,
447 const void *vendor_code,
448 efi_status_t (*progress)(efi_uintn_t completion),
449 u16 **abort_reason)
450{
Vincent Stehlé8645aef2022-05-31 09:55:34 +0200451 efi_status_t status;
Masahisa Kojimabfaa1fb2023-06-07 14:41:52 +0900452 struct fmp_state state = { 0 };
Vincent Stehlé8645aef2022-05-31 09:55:34 +0200453
Heinrich Schuchardtb1193fa2022-02-03 20:13:17 +0100454 EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900455 image_size, vendor_code, progress, abort_reason);
456
457 if (!image || image_index != 1)
458 return EFI_EXIT(EFI_INVALID_PARAMETER);
459
Masahisa Kojimabfaa1fb2023-06-07 14:41:52 +0900460 status = efi_firmware_verify_image(&image, &image_size, image_index,
461 &state);
Vincent Stehlé8645aef2022-05-31 09:55:34 +0200462 if (status != EFI_SUCCESS)
463 return EFI_EXIT(status);
464
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900465 if (fit_update(image))
466 return EFI_EXIT(EFI_DEVICE_ERROR);
467
Masahisa Kojimabfaa1fb2023-06-07 14:41:52 +0900468 efi_firmware_set_fmp_state_var(&state, image_index);
469
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900470 return EFI_EXIT(EFI_SUCCESS);
471}
472
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900473const struct efi_firmware_management_protocol efi_fmp_fit = {
Sughosh Ganu556a1262022-06-01 23:30:41 +0530474 .get_image_info = efi_firmware_get_image_info,
AKASHI Takahirof27c2012020-11-30 18:12:12 +0900475 .get_image = efi_firmware_get_image_unsupported,
476 .set_image = efi_firmware_fit_set_image,
477 .check_image = efi_firmware_check_image_unsupported,
478 .get_package_info = efi_firmware_get_package_info_unsupported,
479 .set_package_info = efi_firmware_set_package_info_unsupported,
480};
AKASHI Takahirobb7e71d2020-11-17 09:28:00 +0900481#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_FIT */
482
483#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_RAW
484/*
485 * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update
486 * method with raw data.
487 */
AKASHI Takahirobb7e71d2020-11-17 09:28:00 +0900488
489/**
AKASHI Takahirobb7e71d2020-11-17 09:28:00 +0900490 * efi_firmware_raw_set_image - update the firmware image
491 * @this: Protocol instance
492 * @image_index: Image index number
493 * @image: New image
494 * @image_size: Size of new image
495 * @vendor_code: Vendor-specific update policy
496 * @progress: Function to report the progress of update
497 * @abort_reason: Pointer to string of abort reason
498 *
499 * Update the firmware to new image, using dfu. The new image should
500 * be a single raw image.
501 * @vendor_code, @progress and @abort_reason are not supported.
502 *
503 * Return: status code
504 */
505static
506efi_status_t EFIAPI efi_firmware_raw_set_image(
507 struct efi_firmware_management_protocol *this,
508 u8 image_index,
509 const void *image,
510 efi_uintn_t image_size,
511 const void *vendor_code,
512 efi_status_t (*progress)(efi_uintn_t completion),
513 u16 **abort_reason)
514{
Sughosh Ganu86794052022-10-21 18:16:03 +0530515 int ret;
Sughosh Ganu88a2ef22020-12-30 19:27:10 +0530516 efi_status_t status;
Masahisa Kojimabfaa1fb2023-06-07 14:41:52 +0900517 struct fmp_state state = { 0 };
Sughosh Ganu675b62e2020-12-30 19:27:05 +0530518
Heinrich Schuchardtb1193fa2022-02-03 20:13:17 +0100519 EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image,
AKASHI Takahirobb7e71d2020-11-17 09:28:00 +0900520 image_size, vendor_code, progress, abort_reason);
521
522 if (!image)
523 return EFI_EXIT(EFI_INVALID_PARAMETER);
524
Masahisa Kojimabfaa1fb2023-06-07 14:41:52 +0900525 status = efi_firmware_verify_image(&image, &image_size, image_index,
526 &state);
Vincent Stehlé8645aef2022-05-31 09:55:34 +0200527 if (status != EFI_SUCCESS)
528 return EFI_EXIT(status);
Sughosh Ganu675b62e2020-12-30 19:27:05 +0530529
Sughosh Ganu86794052022-10-21 18:16:03 +0530530 if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
531 /*
532 * Based on the value of update bank, derive the
533 * image index value.
534 */
535 ret = fwu_get_image_index(&image_index);
536 if (ret) {
537 log_debug("Unable to get FWU image_index\n");
538 return EFI_EXIT(EFI_DEVICE_ERROR);
539 }
540 }
541
AKASHI Takahirobb7e71d2020-11-17 09:28:00 +0900542 if (dfu_write_by_alt(image_index - 1, (void *)image, image_size,
543 NULL, NULL))
544 return EFI_EXIT(EFI_DEVICE_ERROR);
545
Masahisa Kojimabfaa1fb2023-06-07 14:41:52 +0900546 efi_firmware_set_fmp_state_var(&state, image_index);
547
AKASHI Takahirobb7e71d2020-11-17 09:28:00 +0900548 return EFI_EXIT(EFI_SUCCESS);
549}
550
551const struct efi_firmware_management_protocol efi_fmp_raw = {
Sughosh Ganu556a1262022-06-01 23:30:41 +0530552 .get_image_info = efi_firmware_get_image_info,
AKASHI Takahirobb7e71d2020-11-17 09:28:00 +0900553 .get_image = efi_firmware_get_image_unsupported,
554 .set_image = efi_firmware_raw_set_image,
555 .check_image = efi_firmware_check_image_unsupported,
556 .get_package_info = efi_firmware_get_package_info_unsupported,
557 .set_package_info = efi_firmware_set_package_info_unsupported,
558};
559#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_RAW */