blob: f00440163d4189a5a34f6950c3457d341f1589c9 [file] [log] [blame]
AKASHI Takahiro473d9b32020-11-17 09:27:55 +09001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * EFI Capsule
4 *
5 * Copyright (c) 2018 Linaro Limited
6 * Author: AKASHI Takahiro
7 */
8
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02009#define LOG_CATEGORY LOGC_EFI
10
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090011#include <common.h>
12#include <efi_loader.h>
13#include <efi_variable.h>
AKASHI Takahirob71a0ae2021-10-07 15:23:32 +090014#include <env.h>
15#include <fdtdec.h>
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090016#include <fs.h>
Masami Hiramatsu4b2f8c12022-02-16 15:16:12 +090017#include <hang.h>
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090018#include <malloc.h>
AKASHI Takahiro45b819542020-11-17 09:27:56 +090019#include <mapmem.h>
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090020#include <sort.h>
AKASHI Takahirob71a0ae2021-10-07 15:23:32 +090021#include <asm/global_data.h>
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090022
Sughosh Ganu586bb982020-12-30 19:27:09 +053023#include <crypto/pkcs7.h>
24#include <crypto/pkcs7_parser.h>
25#include <linux/err.h>
26
AKASHI Takahirob71a0ae2021-10-07 15:23:32 +090027DECLARE_GLOBAL_DATA_PTR;
28
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090029const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID;
AKASHI Takahiro0d963782020-11-30 18:12:11 +090030static const efi_guid_t efi_guid_firmware_management_capsule_id =
31 EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
32const efi_guid_t efi_guid_firmware_management_protocol =
33 EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090034
AKASHI Takahiro45b819542020-11-17 09:27:56 +090035#ifdef CONFIG_EFI_CAPSULE_ON_DISK
36/* for file system access */
37static struct efi_file_handle *bootdev_root;
38#endif
39
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090040/**
41 * get_last_capsule - get the last capsule index
42 *
43 * Retrieve the index of the capsule invoked last time from "CapsuleLast"
44 * variable.
45 *
46 * Return:
47 * * > 0 - the last capsule index invoked
48 * * 0xffff - on error, or no capsule invoked yet
49 */
50static __maybe_unused unsigned int get_last_capsule(void)
51{
52 u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010053 char value[5];
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090054 efi_uintn_t size;
55 unsigned long index = 0xffff;
56 efi_status_t ret;
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010057 int i;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090058
59 size = sizeof(value16);
Simon Glass90975372022-01-23 12:55:12 -070060 ret = efi_get_variable_int(u"CapsuleLast", &efi_guid_capsule_report,
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090061 NULL, &size, value16, NULL);
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010062 if (ret != EFI_SUCCESS || size != 22 ||
Simon Glass90975372022-01-23 12:55:12 -070063 u16_strncmp(value16, u"Capsule", 7))
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090064 goto err;
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010065 for (i = 0; i < 4; ++i) {
66 u16 c = value16[i + 7];
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090067
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010068 if (!c || c > 0x7f)
69 goto err;
70 value[i] = c;
71 }
72 value[4] = 0;
73 if (strict_strtoul(value, 16, &index))
74 index = 0xffff;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090075err:
76 return index;
77}
78
79/**
80 * set_capsule_result - set a result variable
81 * @capsule: Capsule
82 * @return_status: Return status
83 *
84 * Create and set a result variable, "CapsuleXXXX", for the capsule,
85 * @capsule.
86 */
87static __maybe_unused
88void set_capsule_result(int index, struct efi_capsule_header *capsule,
89 efi_status_t return_status)
90{
91 u16 variable_name16[12];
92 struct efi_capsule_result_variable_header result;
93 struct efi_time time;
94 efi_status_t ret;
95
Ilias Apalodimas21575292020-12-31 12:26:46 +020096 efi_create_indexed_name(variable_name16, sizeof(variable_name16),
97 "Capsule", index);
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090098 result.variable_total_size = sizeof(result);
99 result.capsule_guid = capsule->capsule_guid;
100 ret = EFI_CALL((*efi_runtime_services.get_time)(&time, NULL));
101 if (ret == EFI_SUCCESS)
102 memcpy(&result.capsule_processed, &time, sizeof(time));
103 else
104 memset(&result.capsule_processed, 0, sizeof(time));
105 result.capsule_status = return_status;
Heinrich Schuchardt24adaa72021-07-10 11:10:26 +0200106 ret = efi_set_variable_int(variable_name16, &efi_guid_capsule_report,
107 EFI_VARIABLE_NON_VOLATILE |
108 EFI_VARIABLE_BOOTSERVICE_ACCESS |
109 EFI_VARIABLE_RUNTIME_ACCESS,
110 sizeof(result), &result, false);
Heinrich Schuchardtb1fae8c2021-07-10 11:14:13 +0200111 if (ret != EFI_SUCCESS) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200112 log_err("Setting %ls failed\n", variable_name16);
Heinrich Schuchardtb1fae8c2021-07-10 11:14:13 +0200113 return;
114 }
115
116 /* Variable CapsuleLast must not include terminating 0x0000 */
Simon Glass90975372022-01-23 12:55:12 -0700117 ret = efi_set_variable_int(u"CapsuleLast", &efi_guid_capsule_report,
Heinrich Schuchardtb1fae8c2021-07-10 11:14:13 +0200118 EFI_VARIABLE_READ_ONLY |
119 EFI_VARIABLE_NON_VOLATILE |
120 EFI_VARIABLE_BOOTSERVICE_ACCESS |
121 EFI_VARIABLE_RUNTIME_ACCESS,
122 22, variable_name16, false);
123 if (ret != EFI_SUCCESS)
Simon Glass90975372022-01-23 12:55:12 -0700124 log_err("Setting %ls failed\n", u"CapsuleLast");
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900125}
126
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900127#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT
128/**
129 * efi_fmp_find - search for Firmware Management Protocol drivers
130 * @image_type: Image type guid
131 * @instance: Instance number
132 * @handles: Handles of FMP drivers
133 * @no_handles: Number of handles
134 *
135 * Search for Firmware Management Protocol drivers, matching the image
136 * type, @image_type and the machine instance, @instance, from the list,
137 * @handles.
138 *
139 * Return:
140 * * Protocol instance - on success
141 * * NULL - on failure
142 */
143static struct efi_firmware_management_protocol *
144efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles,
145 efi_uintn_t no_handles)
146{
147 efi_handle_t *handle;
148 struct efi_firmware_management_protocol *fmp;
149 struct efi_firmware_image_descriptor *image_info, *desc;
150 efi_uintn_t info_size, descriptor_size;
151 u32 descriptor_version;
152 u8 descriptor_count;
153 u32 package_version;
154 u16 *package_version_name;
155 bool found = false;
156 int i, j;
157 efi_status_t ret;
158
159 for (i = 0, handle = handles; i < no_handles; i++, handle++) {
160 ret = EFI_CALL(efi_handle_protocol(
161 *handle,
162 &efi_guid_firmware_management_protocol,
163 (void **)&fmp));
164 if (ret != EFI_SUCCESS)
165 continue;
166
167 /* get device's image info */
168 info_size = 0;
169 image_info = NULL;
170 descriptor_version = 0;
171 descriptor_count = 0;
172 descriptor_size = 0;
173 package_version = 0;
174 package_version_name = NULL;
175 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
176 image_info,
177 &descriptor_version,
178 &descriptor_count,
179 &descriptor_size,
180 &package_version,
181 &package_version_name));
182 if (ret != EFI_BUFFER_TOO_SMALL)
183 goto skip;
184
185 image_info = malloc(info_size);
186 if (!image_info)
187 goto skip;
188
189 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
190 image_info,
191 &descriptor_version,
192 &descriptor_count,
193 &descriptor_size,
194 &package_version,
195 &package_version_name));
196 if (ret != EFI_SUCCESS ||
197 descriptor_version != EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION)
198 goto skip;
199
200 /* matching */
201 for (j = 0, desc = image_info; j < descriptor_count;
202 j++, desc = (void *)desc + descriptor_size) {
203 log_debug("+++ desc[%d] index: %d, name: %ls\n",
204 j, desc->image_index, desc->image_id_name);
205 if (!guidcmp(&desc->image_type_id, image_type) &&
206 (!instance ||
207 !desc->hardware_instance ||
208 desc->hardware_instance == instance))
209 found = true;
210 }
211
212skip:
213 efi_free_pool(package_version_name);
214 free(image_info);
215 EFI_CALL(efi_close_protocol(
216 (efi_handle_t)fmp,
217 &efi_guid_firmware_management_protocol,
218 NULL, NULL));
219 if (found)
220 return fmp;
221 }
222
223 return NULL;
224}
225
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900226/**
227 * efi_remove_auth_hdr - remove authentication data from image
228 * @image: Pointer to pointer to Image
229 * @image_size: Pointer to Image size
230 *
231 * Remove the authentication data from image if possible.
232 * Update @image and @image_size.
233 *
234 * Return: status code
235 */
236static efi_status_t efi_remove_auth_hdr(void **image, efi_uintn_t *image_size)
237{
238 struct efi_firmware_image_authentication *auth_hdr;
239 efi_status_t ret = EFI_INVALID_PARAMETER;
240
241 auth_hdr = (struct efi_firmware_image_authentication *)*image;
242 if (*image_size < sizeof(*auth_hdr))
243 goto out;
244
245 if (auth_hdr->auth_info.hdr.dwLength <=
246 offsetof(struct win_certificate_uefi_guid, cert_data))
247 goto out;
248
249 *image = (uint8_t *)*image + sizeof(auth_hdr->monotonic_count) +
250 auth_hdr->auth_info.hdr.dwLength;
251 *image_size = *image_size - auth_hdr->auth_info.hdr.dwLength -
252 sizeof(auth_hdr->monotonic_count);
253
254 ret = EFI_SUCCESS;
255out:
256 return ret;
257}
258
Sughosh Ganu586bb982020-12-30 19:27:09 +0530259#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE)
AKASHI Takahirof155bf52021-11-02 09:55:01 +0900260int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len)
AKASHI Takahirob71a0ae2021-10-07 15:23:32 +0900261{
262 const void *fdt_blob = gd->fdt_blob;
263 const void *blob;
264 const char *cnode_name = "capsule-key";
265 const char *snode_name = "signature";
266 int sig_node;
267 int len;
268
269 sig_node = fdt_subnode_offset(fdt_blob, 0, snode_name);
270 if (sig_node < 0) {
271 log_err("Unable to get signature node offset\n");
272
273 return -FDT_ERR_NOTFOUND;
274 }
275
276 blob = fdt_getprop(fdt_blob, sig_node, cnode_name, &len);
277
278 if (!blob || len < 0) {
279 log_err("Unable to get capsule-key value\n");
280 *pkey = NULL;
281 *pkey_len = 0;
282
283 return -FDT_ERR_NOTFOUND;
284 }
285
286 *pkey = (void *)blob;
287 *pkey_len = len;
288
289 return 0;
290}
Sughosh Ganu586bb982020-12-30 19:27:09 +0530291
Sughosh Ganu586bb982020-12-30 19:27:09 +0530292efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
293 void **image, efi_uintn_t *image_size)
294{
295 u8 *buf;
296 int ret;
Simon Glass1f78c122021-08-02 08:44:31 -0600297 void *fdt_pkey, *pkey;
Sughosh Ganu586bb982020-12-30 19:27:09 +0530298 efi_uintn_t pkey_len;
299 uint64_t monotonic_count;
300 struct efi_signature_store *truststore;
301 struct pkcs7_message *capsule_sig;
302 struct efi_image_regions *regs;
303 struct efi_firmware_image_authentication *auth_hdr;
304 efi_status_t status;
305
306 status = EFI_SECURITY_VIOLATION;
307 capsule_sig = NULL;
308 truststore = NULL;
309 regs = NULL;
310
311 /* Sanity checks */
312 if (capsule == NULL || capsule_size == 0)
313 goto out;
314
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900315 *image = (uint8_t *)capsule;
316 *image_size = capsule_size;
317 if (efi_remove_auth_hdr(image, image_size) != EFI_SUCCESS)
Sughosh Ganu586bb982020-12-30 19:27:09 +0530318 goto out;
319
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900320 auth_hdr = (struct efi_firmware_image_authentication *)capsule;
Sughosh Ganu586bb982020-12-30 19:27:09 +0530321 if (guidcmp(&auth_hdr->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
322 goto out;
323
Sughosh Ganu586bb982020-12-30 19:27:09 +0530324 memcpy(&monotonic_count, &auth_hdr->monotonic_count,
325 sizeof(monotonic_count));
326
327 /* data to be digested */
328 regs = calloc(sizeof(*regs) + sizeof(struct image_region) * 2, 1);
329 if (!regs)
330 goto out;
331
332 regs->max = 2;
333 efi_image_region_add(regs, (uint8_t *)*image,
334 (uint8_t *)*image + *image_size, 1);
335
336 efi_image_region_add(regs, (uint8_t *)&monotonic_count,
337 (uint8_t *)&monotonic_count + sizeof(monotonic_count),
338 1);
339
340 capsule_sig = efi_parse_pkcs7_header(auth_hdr->auth_info.cert_data,
341 auth_hdr->auth_info.hdr.dwLength
342 - sizeof(auth_hdr->auth_info),
343 &buf);
344 if (IS_ERR(capsule_sig)) {
345 debug("Parsing variable's pkcs7 header failed\n");
346 capsule_sig = NULL;
347 goto out;
348 }
349
Simon Glass1f78c122021-08-02 08:44:31 -0600350 ret = efi_get_public_key_data(&fdt_pkey, &pkey_len);
Sughosh Ganu586bb982020-12-30 19:27:09 +0530351 if (ret < 0)
352 goto out;
353
354 pkey = malloc(pkey_len);
355 if (!pkey)
356 goto out;
357
Simon Glass1f78c122021-08-02 08:44:31 -0600358 memcpy(pkey, fdt_pkey, pkey_len);
Sughosh Ganu586bb982020-12-30 19:27:09 +0530359 truststore = efi_build_signature_store(pkey, pkey_len);
360 if (!truststore)
361 goto out;
362
363 /* verify signature */
364 if (efi_signature_verify(regs, capsule_sig, truststore, NULL)) {
365 debug("Verified\n");
366 } else {
367 debug("Verifying variable's signature failed\n");
368 goto out;
369 }
370
371 status = EFI_SUCCESS;
372
373out:
374 efi_sigstore_free(truststore);
375 pkcs7_free_message(capsule_sig);
376 free(regs);
377
378 return status;
379}
380#else
381efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
382 void **image, efi_uintn_t *image_size)
383{
384 return EFI_UNSUPPORTED;
385}
386#endif /* CONFIG_EFI_CAPSULE_AUTHENTICATE */
387
388
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900389/**
390 * efi_capsule_update_firmware - update firmware from capsule
391 * @capsule_data: Capsule
392 *
393 * Update firmware, using a capsule, @capsule_data. Loading any FMP
394 * drivers embedded in a capsule is not supported.
395 *
396 * Return: status code
397 */
398static efi_status_t efi_capsule_update_firmware(
399 struct efi_capsule_header *capsule_data)
400{
401 struct efi_firmware_management_capsule_header *capsule;
402 struct efi_firmware_management_capsule_image_header *image;
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900403 size_t capsule_size, image_binary_size;
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900404 void *image_binary, *vendor_code;
405 efi_handle_t *handles;
406 efi_uintn_t no_handles;
407 int item;
408 struct efi_firmware_management_protocol *fmp;
409 u16 *abort_reason;
410 efi_status_t ret = EFI_SUCCESS;
411
412 /* sanity check */
413 if (capsule_data->header_size < sizeof(*capsule) ||
414 capsule_data->header_size >= capsule_data->capsule_image_size)
415 return EFI_INVALID_PARAMETER;
416
417 capsule = (void *)capsule_data + capsule_data->header_size;
418 capsule_size = capsule_data->capsule_image_size
419 - capsule_data->header_size;
420
421 if (capsule->version != 0x00000001)
422 return EFI_UNSUPPORTED;
423
424 handles = NULL;
425 ret = EFI_CALL(efi_locate_handle_buffer(
426 BY_PROTOCOL,
427 &efi_guid_firmware_management_protocol,
428 NULL, &no_handles, (efi_handle_t **)&handles));
429 if (ret != EFI_SUCCESS)
430 return EFI_UNSUPPORTED;
431
432 /* Payload */
433 for (item = capsule->embedded_driver_count;
434 item < capsule->embedded_driver_count
435 + capsule->payload_item_count; item++) {
436 /* sanity check */
437 if ((capsule->item_offset_list[item] + sizeof(*image)
438 >= capsule_size)) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200439 log_err("Capsule does not have enough data\n");
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900440 ret = EFI_INVALID_PARAMETER;
441 goto out;
442 }
443
444 image = (void *)capsule + capsule->item_offset_list[item];
445
446 if (image->version != 0x00000003) {
447 ret = EFI_UNSUPPORTED;
448 goto out;
449 }
450
451 /* find a device for update firmware */
452 /* TODO: should we pass index as well, or nothing but type? */
453 fmp = efi_fmp_find(&image->update_image_type_id,
454 image->update_hardware_instance,
455 handles, no_handles);
456 if (!fmp) {
Heinrich Schuchardt282249d2022-01-16 14:15:31 +0100457 log_err("FMP driver not found for firmware type %pUs, hardware instance %lld\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900458 &image->update_image_type_id,
459 image->update_hardware_instance);
460 ret = EFI_UNSUPPORTED;
461 goto out;
462 }
463
464 /* do update */
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900465 if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
466 !(image->image_capsule_support &
467 CAPSULE_SUPPORT_AUTHENTICATION)) {
468 /* no signature */
469 ret = EFI_SECURITY_VIOLATION;
470 goto out;
471 }
472
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900473 image_binary = (void *)image + sizeof(*image);
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900474 image_binary_size = image->update_image_size;
475 vendor_code = image_binary + image_binary_size;
476 if (!IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
477 (image->image_capsule_support &
478 CAPSULE_SUPPORT_AUTHENTICATION)) {
479 ret = efi_remove_auth_hdr(&image_binary,
480 &image_binary_size);
481 if (ret != EFI_SUCCESS)
482 goto out;
483 }
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900484
485 abort_reason = NULL;
486 ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index,
487 image_binary,
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900488 image_binary_size,
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900489 vendor_code, NULL,
490 &abort_reason));
491 if (ret != EFI_SUCCESS) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200492 log_err("Firmware update failed: %ls\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900493 abort_reason);
494 efi_free_pool(abort_reason);
495 goto out;
496 }
497 }
498
499out:
500 efi_free_pool(handles);
501
502 return ret;
503}
504#else
505static efi_status_t efi_capsule_update_firmware(
506 struct efi_capsule_header *capsule_data)
507{
508 return EFI_UNSUPPORTED;
509}
510#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT */
511
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900512/**
513 * efi_update_capsule() - process information from operating system
514 * @capsule_header_array: Array of virtual address pointers
515 * @capsule_count: Number of pointers in capsule_header_array
516 * @scatter_gather_list: Array of physical address pointers
517 *
518 * This function implements the UpdateCapsule() runtime service.
519 *
520 * See the Unified Extensible Firmware Interface (UEFI) specification for
521 * details.
522 *
523 * Return: status code
524 */
525efi_status_t EFIAPI efi_update_capsule(
526 struct efi_capsule_header **capsule_header_array,
527 efi_uintn_t capsule_count,
528 u64 scatter_gather_list)
529{
530 struct efi_capsule_header *capsule;
531 unsigned int i;
532 efi_status_t ret;
533
Simon Glass83698b22021-02-07 14:27:02 -0700534 EFI_ENTRY("%p, %zu, %llu\n", capsule_header_array, capsule_count,
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900535 scatter_gather_list);
536
537 if (!capsule_count) {
538 ret = EFI_INVALID_PARAMETER;
539 goto out;
540 }
541
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900542 ret = EFI_SUCCESS;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900543 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
544 i++, capsule = *(++capsule_header_array)) {
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900545 /* sanity check */
546 if (capsule->header_size < sizeof(*capsule) ||
547 capsule->capsule_image_size < sizeof(*capsule)) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200548 log_err("Capsule does not have enough data\n");
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900549 continue;
550 }
551
Heinrich Schuchardt282249d2022-01-16 14:15:31 +0100552 log_debug("Capsule[%d] (guid:%pUs)\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900553 i, &capsule->capsule_guid);
554 if (!guidcmp(&capsule->capsule_guid,
555 &efi_guid_firmware_management_capsule_id)) {
556 ret = efi_capsule_update_firmware(capsule);
557 } else {
Heinrich Schuchardt282249d2022-01-16 14:15:31 +0100558 log_err("Unsupported capsule type: %pUs\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900559 &capsule->capsule_guid);
560 ret = EFI_UNSUPPORTED;
561 }
562
563 if (ret != EFI_SUCCESS)
564 goto out;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900565 }
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000566
567 if (IS_ENABLED(CONFIG_EFI_ESRT)) {
568 /* Rebuild the ESRT to reflect any updated FW images. */
569 ret = efi_esrt_populate();
570 if (ret != EFI_SUCCESS)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200571 log_warning("ESRT update failed\n");
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000572 }
Jose Marinhoaf886ce2021-04-19 14:54:33 +0100573out:
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000574
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900575 return EFI_EXIT(ret);
576}
577
578/**
579 * efi_query_capsule_caps() - check if capsule is supported
580 * @capsule_header_array: Array of virtual pointers
581 * @capsule_count: Number of pointers in capsule_header_array
582 * @maximum_capsule_size: Maximum capsule size
583 * @reset_type: Type of reset needed for capsule update
584 *
585 * This function implements the QueryCapsuleCapabilities() runtime service.
586 *
587 * See the Unified Extensible Firmware Interface (UEFI) specification for
588 * details.
589 *
590 * Return: status code
591 */
592efi_status_t EFIAPI efi_query_capsule_caps(
593 struct efi_capsule_header **capsule_header_array,
594 efi_uintn_t capsule_count,
595 u64 *maximum_capsule_size,
596 u32 *reset_type)
597{
598 struct efi_capsule_header *capsule __attribute__((unused));
599 unsigned int i;
600 efi_status_t ret;
601
Simon Glass83698b22021-02-07 14:27:02 -0700602 EFI_ENTRY("%p, %zu, %p, %p\n", capsule_header_array, capsule_count,
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900603 maximum_capsule_size, reset_type);
604
605 if (!maximum_capsule_size) {
606 ret = EFI_INVALID_PARAMETER;
607 goto out;
608 }
609
610 *maximum_capsule_size = U64_MAX;
611 *reset_type = EFI_RESET_COLD;
612
613 ret = EFI_SUCCESS;
614 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
615 i++, capsule = *(++capsule_header_array)) {
616 /* TODO */
617 }
618out:
619 return EFI_EXIT(ret);
620}
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900621
622#ifdef CONFIG_EFI_CAPSULE_ON_DISK
623/**
624 * get_dp_device - retrieve a device path from boot variable
625 * @boot_var: Boot variable name
626 * @device_dp Device path
627 *
628 * Retrieve a device patch from boot variable, @boot_var.
629 *
630 * Return: status code
631 */
632static efi_status_t get_dp_device(u16 *boot_var,
633 struct efi_device_path **device_dp)
634{
635 void *buf = NULL;
636 efi_uintn_t size;
637 struct efi_load_option lo;
638 struct efi_device_path *file_dp;
639 efi_status_t ret;
640
641 size = 0;
642 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
643 NULL, &size, NULL, NULL);
644 if (ret == EFI_BUFFER_TOO_SMALL) {
645 buf = malloc(size);
646 if (!buf)
647 return EFI_OUT_OF_RESOURCES;
648 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
649 NULL, &size, buf, NULL);
650 }
651 if (ret != EFI_SUCCESS)
652 return ret;
653
654 efi_deserialize_load_option(&lo, buf, &size);
655
656 if (lo.attributes & LOAD_OPTION_ACTIVE) {
657 efi_dp_split_file_path(lo.file_path, device_dp, &file_dp);
658 efi_free_pool(file_dp);
659
660 ret = EFI_SUCCESS;
661 } else {
662 ret = EFI_NOT_FOUND;
663 }
664
665 free(buf);
666
667 return ret;
668}
669
670/**
671 * device_is_present_and_system_part - check if a device exists
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900672 *
673 * Check if a device pointed to by the device path, @dp, exists and is
674 * located in UEFI system partition.
675 *
Heinrich Schuchardta76fc032022-03-05 00:36:50 +0100676 * @dp device path
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900677 * Return: true - yes, false - no
678 */
679static bool device_is_present_and_system_part(struct efi_device_path *dp)
680{
681 efi_handle_t handle;
Heinrich Schuchardta76fc032022-03-05 00:36:50 +0100682 struct efi_device_path *rem;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900683
Heinrich Schuchardta76fc032022-03-05 00:36:50 +0100684 /* Check device exists */
Heinrich Schuchardt0a04a412022-03-19 06:35:43 +0100685 handle = efi_dp_find_obj(dp, NULL, NULL);
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900686 if (!handle)
687 return false;
688
Heinrich Schuchardta76fc032022-03-05 00:36:50 +0100689 /* Check device is on system partition */
690 handle = efi_dp_find_obj(dp, &efi_system_partition_guid, &rem);
691 if (!handle)
692 return false;
693
694 return true;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900695}
696
697/**
698 * find_boot_device - identify the boot device
699 *
700 * Identify the boot device from boot-related variables as UEFI
701 * specification describes and put its handle into bootdev_root.
702 *
703 * Return: status code
704 */
705static efi_status_t find_boot_device(void)
706{
707 char boot_var[9];
708 u16 boot_var16[9], *p, bootnext, *boot_order = NULL;
709 efi_uintn_t size;
710 int i, num;
711 struct efi_simple_file_system_protocol *volume;
712 struct efi_device_path *boot_dev = NULL;
713 efi_status_t ret;
714
715 /* find active boot device in BootNext */
716 bootnext = 0;
717 size = sizeof(bootnext);
Simon Glass90975372022-01-23 12:55:12 -0700718 ret = efi_get_variable_int(u"BootNext",
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900719 (efi_guid_t *)&efi_global_variable_guid,
720 NULL, &size, &bootnext, NULL);
721 if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
722 /* BootNext does exist here */
723 if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16)) {
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900724 log_err("BootNext must be 16-bit integer\n");
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900725 goto skip;
726 }
727 sprintf((char *)boot_var, "Boot%04X", bootnext);
728 p = boot_var16;
729 utf8_utf16_strcpy(&p, boot_var);
730
731 ret = get_dp_device(boot_var16, &boot_dev);
732 if (ret == EFI_SUCCESS) {
733 if (device_is_present_and_system_part(boot_dev)) {
Masami Hiramatsu10165752021-07-12 18:05:17 +0900734 goto found;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900735 } else {
736 efi_free_pool(boot_dev);
737 boot_dev = NULL;
738 }
739 }
740 }
741
742skip:
743 /* find active boot device in BootOrder */
744 size = 0;
Simon Glass90975372022-01-23 12:55:12 -0700745 ret = efi_get_variable_int(u"BootOrder", &efi_global_variable_guid,
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900746 NULL, &size, NULL, NULL);
747 if (ret == EFI_BUFFER_TOO_SMALL) {
748 boot_order = malloc(size);
749 if (!boot_order) {
750 ret = EFI_OUT_OF_RESOURCES;
751 goto out;
752 }
753
Simon Glass90975372022-01-23 12:55:12 -0700754 ret = efi_get_variable_int(u"BootOrder",
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900755 &efi_global_variable_guid,
756 NULL, &size, boot_order, NULL);
757 }
758 if (ret != EFI_SUCCESS)
759 goto out;
760
761 /* check in higher order */
762 num = size / sizeof(u16);
763 for (i = 0; i < num; i++) {
764 sprintf((char *)boot_var, "Boot%04X", boot_order[i]);
765 p = boot_var16;
766 utf8_utf16_strcpy(&p, boot_var);
767 ret = get_dp_device(boot_var16, &boot_dev);
768 if (ret != EFI_SUCCESS)
769 continue;
770
771 if (device_is_present_and_system_part(boot_dev))
772 break;
773
774 efi_free_pool(boot_dev);
775 boot_dev = NULL;
776 }
Masami Hiramatsu10165752021-07-12 18:05:17 +0900777found:
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900778 if (boot_dev) {
Masami Hiramatsud9763bb2021-07-14 14:19:13 +0900779 log_debug("Boot device %pD\n", boot_dev);
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900780
781 volume = efi_fs_from_path(boot_dev);
782 if (!volume)
783 ret = EFI_DEVICE_ERROR;
784 else
785 ret = EFI_CALL(volume->open_volume(volume,
786 &bootdev_root));
787 efi_free_pool(boot_dev);
788 } else {
789 ret = EFI_NOT_FOUND;
790 }
AKASHI Takahirofa390e62021-04-20 10:03:16 +0900791out:
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900792 free(boot_order);
793
794 return ret;
795}
796
797/**
798 * efi_capsule_scan_dir - traverse a capsule directory in boot device
799 * @files: Array of file names
800 * @num: Number of elements in @files
801 *
802 * Traverse a capsule directory in boot device.
803 * Called by initialization code, and returns an array of capsule file
804 * names in @files.
805 *
806 * Return: status code
807 */
808static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num)
809{
810 struct efi_file_handle *dirh;
811 struct efi_file_info *dirent;
812 efi_uintn_t dirent_size, tmp_size;
813 unsigned int count;
814 u16 **tmp_files;
815 efi_status_t ret;
816
817 ret = find_boot_device();
818 if (ret == EFI_NOT_FOUND) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200819 log_debug("Boot device is not set\n");
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900820 *num = 0;
821 return EFI_SUCCESS;
822 } else if (ret != EFI_SUCCESS) {
823 return EFI_DEVICE_ERROR;
824 }
825
826 /* count capsule files */
827 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
828 EFI_CAPSULE_DIR,
829 EFI_FILE_MODE_READ, 0));
830 if (ret != EFI_SUCCESS) {
831 *num = 0;
832 return EFI_SUCCESS;
833 }
834
835 dirent_size = 256;
836 dirent = malloc(dirent_size);
837 if (!dirent)
838 return EFI_OUT_OF_RESOURCES;
839
840 count = 0;
841 while (1) {
842 tmp_size = dirent_size;
843 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
844 if (ret == EFI_BUFFER_TOO_SMALL) {
Heinrich Schuchardtaa27e5d2021-04-11 06:53:04 +0200845 struct efi_file_info *old_dirent = dirent;
846
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900847 dirent = realloc(dirent, tmp_size);
848 if (!dirent) {
Heinrich Schuchardtaa27e5d2021-04-11 06:53:04 +0200849 dirent = old_dirent;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900850 ret = EFI_OUT_OF_RESOURCES;
851 goto err;
852 }
853 dirent_size = tmp_size;
854 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
855 }
856 if (ret != EFI_SUCCESS)
857 goto err;
858 if (!tmp_size)
859 break;
860
Heinrich Schuchardt76b708a2021-02-09 17:45:33 +0100861 if (!(dirent->attribute & EFI_FILE_DIRECTORY))
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900862 count++;
863 }
864
865 ret = EFI_CALL((*dirh->setpos)(dirh, 0));
866 if (ret != EFI_SUCCESS)
867 goto err;
868
869 /* make a list */
AKASHI Takahiroc8fc12f2021-01-22 10:43:27 +0900870 tmp_files = malloc(count * sizeof(*tmp_files));
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900871 if (!tmp_files) {
872 ret = EFI_OUT_OF_RESOURCES;
873 goto err;
874 }
875
876 count = 0;
877 while (1) {
878 tmp_size = dirent_size;
879 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
880 if (ret != EFI_SUCCESS)
881 goto err;
882 if (!tmp_size)
883 break;
884
885 if (!(dirent->attribute & EFI_FILE_DIRECTORY) &&
Simon Glass90975372022-01-23 12:55:12 -0700886 u16_strcmp(dirent->file_name, u".") &&
887 u16_strcmp(dirent->file_name, u".."))
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900888 tmp_files[count++] = u16_strdup(dirent->file_name);
889 }
890 /* ignore an error */
891 EFI_CALL((*dirh->close)(dirh));
892
893 /* in ascii order */
894 /* FIXME: u16 version of strcasecmp */
895 qsort(tmp_files, count, sizeof(*tmp_files),
896 (int (*)(const void *, const void *))strcasecmp);
897 *files = tmp_files;
898 *num = count;
899 ret = EFI_SUCCESS;
900err:
901 free(dirent);
902
903 return ret;
904}
905
906/**
907 * efi_capsule_read_file - read in a capsule file
908 * @filename: File name
909 * @capsule: Pointer to buffer for capsule
910 *
911 * Read a capsule file and put its content in @capsule.
912 *
913 * Return: status code
914 */
915static efi_status_t efi_capsule_read_file(const u16 *filename,
916 struct efi_capsule_header **capsule)
917{
918 struct efi_file_handle *dirh, *fh;
919 struct efi_file_info *file_info = NULL;
920 struct efi_capsule_header *buf = NULL;
921 efi_uintn_t size;
922 efi_status_t ret;
923
924 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
925 EFI_CAPSULE_DIR,
926 EFI_FILE_MODE_READ, 0));
927 if (ret != EFI_SUCCESS)
928 return ret;
929 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
930 EFI_FILE_MODE_READ, 0));
931 /* ignore an error */
932 EFI_CALL((*dirh->close)(dirh));
933 if (ret != EFI_SUCCESS)
934 return ret;
935
936 /* file size */
937 size = 0;
938 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
939 &size, file_info));
940 if (ret == EFI_BUFFER_TOO_SMALL) {
941 file_info = malloc(size);
942 if (!file_info) {
943 ret = EFI_OUT_OF_RESOURCES;
944 goto err;
945 }
946 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
947 &size, file_info));
948 }
949 if (ret != EFI_SUCCESS)
950 goto err;
951 size = file_info->file_size;
952 free(file_info);
953 buf = malloc(size);
954 if (!buf) {
955 ret = EFI_OUT_OF_RESOURCES;
956 goto err;
957 }
958
959 /* fetch data */
960 ret = EFI_CALL((*fh->read)(fh, &size, buf));
961 if (ret == EFI_SUCCESS) {
962 if (size >= buf->capsule_image_size) {
963 *capsule = buf;
964 } else {
965 free(buf);
966 ret = EFI_INVALID_PARAMETER;
967 }
968 } else {
969 free(buf);
970 }
971err:
972 EFI_CALL((*fh->close)(fh));
973
974 return ret;
975}
976
977/**
978 * efi_capsule_delete_file - delete a capsule file
979 * @filename: File name
980 *
981 * Delete a capsule file from capsule directory.
982 *
983 * Return: status code
984 */
985static efi_status_t efi_capsule_delete_file(const u16 *filename)
986{
987 struct efi_file_handle *dirh, *fh;
988 efi_status_t ret;
989
990 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
991 EFI_CAPSULE_DIR,
992 EFI_FILE_MODE_READ, 0));
993 if (ret != EFI_SUCCESS)
994 return ret;
995 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
996 EFI_FILE_MODE_READ, 0));
997 /* ignore an error */
998 EFI_CALL((*dirh->close)(dirh));
999
Heinrich Schuchardte5c22812021-06-02 19:28:22 +02001000 if (ret == EFI_SUCCESS)
1001 ret = EFI_CALL((*fh->delete)(fh));
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001002
1003 return ret;
1004}
1005
1006/**
1007 * efi_capsule_scan_done - reset a scan help function
1008 *
1009 * Reset a scan help function
1010 */
1011static void efi_capsule_scan_done(void)
1012{
1013 EFI_CALL((*bootdev_root->close)(bootdev_root));
1014 bootdev_root = NULL;
1015}
1016
1017/**
Ilias Apalodimasfac773e2021-06-22 17:38:53 +03001018 * efi_load_capsule_drivers - initialize capsule drivers
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001019 *
Ilias Apalodimasfac773e2021-06-22 17:38:53 +03001020 * Generic FMP drivers backed by DFU
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001021 *
1022 * Return: status code
1023 */
Ilias Apalodimasfac773e2021-06-22 17:38:53 +03001024efi_status_t __weak efi_load_capsule_drivers(void)
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001025{
AKASHI Takahirof4818e62020-11-30 18:12:12 +09001026 __maybe_unused efi_handle_t handle;
1027 efi_status_t ret = EFI_SUCCESS;
1028
1029 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) {
1030 handle = NULL;
1031 ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
1032 &handle, &efi_guid_firmware_management_protocol,
1033 &efi_fmp_fit, NULL));
1034 }
1035
AKASHI Takahiro7ff3f3c2020-11-17 09:28:00 +09001036 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) {
1037 handle = NULL;
1038 ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
Masami Hiramatsuf5388522021-06-22 17:38:51 +03001039 &handle,
AKASHI Takahiro7ff3f3c2020-11-17 09:28:00 +09001040 &efi_guid_firmware_management_protocol,
1041 &efi_fmp_raw, NULL));
1042 }
1043
AKASHI Takahirof4818e62020-11-30 18:12:12 +09001044 return ret;
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001045}
1046
1047/**
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001048 * check_run_capsules() - check whether capsule update should run
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001049 *
1050 * The spec says OsIndications must be set in order to run the capsule update
1051 * on-disk. Since U-Boot doesn't support runtime SetVariable, allow capsules to
1052 * run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001053 *
1054 * Return: EFI_SUCCESS if update to run, EFI_NOT_FOUND otherwise
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001055 */
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001056static efi_status_t check_run_capsules(void)
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001057{
1058 u64 os_indications;
1059 efi_uintn_t size;
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001060 efi_status_t r;
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001061
1062 size = sizeof(os_indications);
Simon Glass90975372022-01-23 12:55:12 -07001063 r = efi_get_variable_int(u"OsIndications", &efi_global_variable_guid,
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001064 NULL, &size, &os_indications, NULL);
1065 if (r != EFI_SUCCESS || size != sizeof(os_indications))
1066 return EFI_NOT_FOUND;
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001067
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001068 if (os_indications &
1069 EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) {
1070 os_indications &=
1071 ~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
Simon Glass90975372022-01-23 12:55:12 -07001072 r = efi_set_variable_int(u"OsIndications",
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001073 &efi_global_variable_guid,
1074 EFI_VARIABLE_NON_VOLATILE |
1075 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1076 EFI_VARIABLE_RUNTIME_ACCESS,
1077 sizeof(os_indications),
1078 &os_indications, false);
1079 if (r != EFI_SUCCESS)
1080 log_err("Setting %ls failed\n", L"OsIndications");
1081 return EFI_SUCCESS;
1082 } else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) {
1083 return EFI_SUCCESS;
1084 } else {
1085 return EFI_NOT_FOUND;
1086 }
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001087}
1088
1089/**
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001090 * efi_launch_capsule - launch capsules
1091 *
1092 * Launch all the capsules in system at boot time.
1093 * Called by efi init code
1094 *
1095 * Return: status codde
1096 */
1097efi_status_t efi_launch_capsules(void)
1098{
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001099 struct efi_capsule_header *capsule = NULL;
1100 u16 **files;
1101 unsigned int nfiles, index, i;
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001102 efi_status_t ret;
1103
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001104 if (check_run_capsules() != EFI_SUCCESS)
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001105 return EFI_SUCCESS;
1106
1107 index = get_last_capsule();
1108
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001109 /*
1110 * Find capsules on disk.
1111 * All the capsules are collected at the beginning because
1112 * capsule files will be removed instantly.
1113 */
1114 nfiles = 0;
1115 files = NULL;
1116 ret = efi_capsule_scan_dir(&files, &nfiles);
1117 if (ret != EFI_SUCCESS)
1118 return ret;
1119 if (!nfiles)
1120 return EFI_SUCCESS;
1121
1122 /* Launch capsules */
1123 for (i = 0, ++index; i < nfiles; i++, index++) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001124 log_debug("Applying %ls\n", files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001125 if (index > 0xffff)
1126 index = 0;
1127 ret = efi_capsule_read_file(files[i], &capsule);
1128 if (ret == EFI_SUCCESS) {
Masami Hiramatsu3454a692022-02-16 15:15:42 +09001129 ret = efi_capsule_update_firmware(capsule);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001130 if (ret != EFI_SUCCESS)
Masami Hiramatsu4b2f8c12022-02-16 15:16:12 +09001131 log_err("Applying capsule %ls failed.\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +09001132 files[i]);
Masami Hiramatsu4b2f8c12022-02-16 15:16:12 +09001133 else
1134 log_info("Applying capsule %ls succeeded.\n",
1135 files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001136
Masami Hiramatsu1001a102021-11-12 22:05:15 +09001137 /* create CapsuleXXXX */
1138 set_capsule_result(index, capsule, ret);
1139
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001140 free(capsule);
1141 } else {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001142 log_err("Reading capsule %ls failed\n", files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001143 }
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001144 /* delete a capsule either in case of success or failure */
1145 ret = efi_capsule_delete_file(files[i]);
1146 if (ret != EFI_SUCCESS)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001147 log_err("Deleting capsule %ls failed\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +09001148 files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001149 }
1150 efi_capsule_scan_done();
1151
1152 for (i = 0; i < nfiles; i++)
1153 free(files[i]);
1154 free(files);
1155
Masami Hiramatsu4b2f8c12022-02-16 15:16:12 +09001156 /*
1157 * UEFI spec requires to reset system after complete processing capsule
1158 * update on the storage.
1159 */
1160 log_info("Reboot after firmware update");
1161 /* Cold reset is required for loading the new firmware. */
1162 do_reset(NULL, 0, 0, NULL);
1163 hang();
1164 /* not reach here */
1165
1166 return 0;
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001167}
1168#endif /* CONFIG_EFI_CAPSULE_ON_DISK */