blob: 3e7ad470d484cf27080b1bddd0eae2f6b9a72b14 [file] [log] [blame]
AKASHI Takahiro2bc27ca2020-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
9#include <common.h>
10#include <efi_loader.h>
11#include <efi_variable.h>
12#include <fs.h>
13#include <malloc.h>
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +090014#include <mapmem.h>
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090015#include <sort.h>
16
17const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID;
AKASHI Takahiro8d990262020-11-30 18:12:11 +090018static const efi_guid_t efi_guid_firmware_management_capsule_id =
19 EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
20const efi_guid_t efi_guid_firmware_management_protocol =
21 EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090022
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +090023#ifdef CONFIG_EFI_CAPSULE_ON_DISK
24/* for file system access */
25static struct efi_file_handle *bootdev_root;
26#endif
27
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090028/**
29 * get_last_capsule - get the last capsule index
30 *
31 * Retrieve the index of the capsule invoked last time from "CapsuleLast"
32 * variable.
33 *
34 * Return:
35 * * > 0 - the last capsule index invoked
36 * * 0xffff - on error, or no capsule invoked yet
37 */
38static __maybe_unused unsigned int get_last_capsule(void)
39{
40 u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */
41 char value[11], *p;
42 efi_uintn_t size;
43 unsigned long index = 0xffff;
44 efi_status_t ret;
45
46 size = sizeof(value16);
47 ret = efi_get_variable_int(L"CapsuleLast", &efi_guid_capsule_report,
48 NULL, &size, value16, NULL);
49 if (ret != EFI_SUCCESS || u16_strncmp(value16, L"Capsule", 7))
50 goto err;
51
52 p = value;
53 utf16_utf8_strcpy(&p, value16);
54 strict_strtoul(&value[7], 16, &index);
55err:
56 return index;
57}
58
59/**
60 * set_capsule_result - set a result variable
61 * @capsule: Capsule
62 * @return_status: Return status
63 *
64 * Create and set a result variable, "CapsuleXXXX", for the capsule,
65 * @capsule.
66 */
67static __maybe_unused
68void set_capsule_result(int index, struct efi_capsule_header *capsule,
69 efi_status_t return_status)
70{
71 u16 variable_name16[12];
72 struct efi_capsule_result_variable_header result;
73 struct efi_time time;
74 efi_status_t ret;
75
76 efi_create_indexed_name(variable_name16, "Capsule", index);
77
78 result.variable_total_size = sizeof(result);
79 result.capsule_guid = capsule->capsule_guid;
80 ret = EFI_CALL((*efi_runtime_services.get_time)(&time, NULL));
81 if (ret == EFI_SUCCESS)
82 memcpy(&result.capsule_processed, &time, sizeof(time));
83 else
84 memset(&result.capsule_processed, 0, sizeof(time));
85 result.capsule_status = return_status;
86 ret = efi_set_variable(variable_name16, &efi_guid_capsule_report,
87 EFI_VARIABLE_NON_VOLATILE |
88 EFI_VARIABLE_BOOTSERVICE_ACCESS |
89 EFI_VARIABLE_RUNTIME_ACCESS,
90 sizeof(result), &result);
91 if (ret)
AKASHI Takahiro8d990262020-11-30 18:12:11 +090092 log_err("EFI: creating %ls failed\n", variable_name16);
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090093}
94
AKASHI Takahiro8d990262020-11-30 18:12:11 +090095#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT
96/**
97 * efi_fmp_find - search for Firmware Management Protocol drivers
98 * @image_type: Image type guid
99 * @instance: Instance number
100 * @handles: Handles of FMP drivers
101 * @no_handles: Number of handles
102 *
103 * Search for Firmware Management Protocol drivers, matching the image
104 * type, @image_type and the machine instance, @instance, from the list,
105 * @handles.
106 *
107 * Return:
108 * * Protocol instance - on success
109 * * NULL - on failure
110 */
111static struct efi_firmware_management_protocol *
112efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles,
113 efi_uintn_t no_handles)
114{
115 efi_handle_t *handle;
116 struct efi_firmware_management_protocol *fmp;
117 struct efi_firmware_image_descriptor *image_info, *desc;
118 efi_uintn_t info_size, descriptor_size;
119 u32 descriptor_version;
120 u8 descriptor_count;
121 u32 package_version;
122 u16 *package_version_name;
123 bool found = false;
124 int i, j;
125 efi_status_t ret;
126
127 for (i = 0, handle = handles; i < no_handles; i++, handle++) {
128 ret = EFI_CALL(efi_handle_protocol(
129 *handle,
130 &efi_guid_firmware_management_protocol,
131 (void **)&fmp));
132 if (ret != EFI_SUCCESS)
133 continue;
134
135 /* get device's image info */
136 info_size = 0;
137 image_info = NULL;
138 descriptor_version = 0;
139 descriptor_count = 0;
140 descriptor_size = 0;
141 package_version = 0;
142 package_version_name = NULL;
143 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
144 image_info,
145 &descriptor_version,
146 &descriptor_count,
147 &descriptor_size,
148 &package_version,
149 &package_version_name));
150 if (ret != EFI_BUFFER_TOO_SMALL)
151 goto skip;
152
153 image_info = malloc(info_size);
154 if (!image_info)
155 goto skip;
156
157 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
158 image_info,
159 &descriptor_version,
160 &descriptor_count,
161 &descriptor_size,
162 &package_version,
163 &package_version_name));
164 if (ret != EFI_SUCCESS ||
165 descriptor_version != EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION)
166 goto skip;
167
168 /* matching */
169 for (j = 0, desc = image_info; j < descriptor_count;
170 j++, desc = (void *)desc + descriptor_size) {
171 log_debug("+++ desc[%d] index: %d, name: %ls\n",
172 j, desc->image_index, desc->image_id_name);
173 if (!guidcmp(&desc->image_type_id, image_type) &&
174 (!instance ||
175 !desc->hardware_instance ||
176 desc->hardware_instance == instance))
177 found = true;
178 }
179
180skip:
181 efi_free_pool(package_version_name);
182 free(image_info);
183 EFI_CALL(efi_close_protocol(
184 (efi_handle_t)fmp,
185 &efi_guid_firmware_management_protocol,
186 NULL, NULL));
187 if (found)
188 return fmp;
189 }
190
191 return NULL;
192}
193
194/**
195 * efi_capsule_update_firmware - update firmware from capsule
196 * @capsule_data: Capsule
197 *
198 * Update firmware, using a capsule, @capsule_data. Loading any FMP
199 * drivers embedded in a capsule is not supported.
200 *
201 * Return: status code
202 */
203static efi_status_t efi_capsule_update_firmware(
204 struct efi_capsule_header *capsule_data)
205{
206 struct efi_firmware_management_capsule_header *capsule;
207 struct efi_firmware_management_capsule_image_header *image;
208 size_t capsule_size;
209 void *image_binary, *vendor_code;
210 efi_handle_t *handles;
211 efi_uintn_t no_handles;
212 int item;
213 struct efi_firmware_management_protocol *fmp;
214 u16 *abort_reason;
215 efi_status_t ret = EFI_SUCCESS;
216
217 /* sanity check */
218 if (capsule_data->header_size < sizeof(*capsule) ||
219 capsule_data->header_size >= capsule_data->capsule_image_size)
220 return EFI_INVALID_PARAMETER;
221
222 capsule = (void *)capsule_data + capsule_data->header_size;
223 capsule_size = capsule_data->capsule_image_size
224 - capsule_data->header_size;
225
226 if (capsule->version != 0x00000001)
227 return EFI_UNSUPPORTED;
228
229 handles = NULL;
230 ret = EFI_CALL(efi_locate_handle_buffer(
231 BY_PROTOCOL,
232 &efi_guid_firmware_management_protocol,
233 NULL, &no_handles, (efi_handle_t **)&handles));
234 if (ret != EFI_SUCCESS)
235 return EFI_UNSUPPORTED;
236
237 /* Payload */
238 for (item = capsule->embedded_driver_count;
239 item < capsule->embedded_driver_count
240 + capsule->payload_item_count; item++) {
241 /* sanity check */
242 if ((capsule->item_offset_list[item] + sizeof(*image)
243 >= capsule_size)) {
244 log_err("EFI: A capsule has not enough data\n");
245 ret = EFI_INVALID_PARAMETER;
246 goto out;
247 }
248
249 image = (void *)capsule + capsule->item_offset_list[item];
250
251 if (image->version != 0x00000003) {
252 ret = EFI_UNSUPPORTED;
253 goto out;
254 }
255
256 /* find a device for update firmware */
257 /* TODO: should we pass index as well, or nothing but type? */
258 fmp = efi_fmp_find(&image->update_image_type_id,
259 image->update_hardware_instance,
260 handles, no_handles);
261 if (!fmp) {
262 log_err("EFI Capsule: driver not found for firmware type: %pUl, hardware instance: %lld\n",
263 &image->update_image_type_id,
264 image->update_hardware_instance);
265 ret = EFI_UNSUPPORTED;
266 goto out;
267 }
268
269 /* do update */
270 image_binary = (void *)image + sizeof(*image);
271 vendor_code = image_binary + image->update_image_size;
272
273 abort_reason = NULL;
274 ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index,
275 image_binary,
276 image->update_image_size,
277 vendor_code, NULL,
278 &abort_reason));
279 if (ret != EFI_SUCCESS) {
280 log_err("EFI Capsule: firmware update failed: %ls\n",
281 abort_reason);
282 efi_free_pool(abort_reason);
283 goto out;
284 }
285 }
286
287out:
288 efi_free_pool(handles);
289
290 return ret;
291}
292#else
293static efi_status_t efi_capsule_update_firmware(
294 struct efi_capsule_header *capsule_data)
295{
296 return EFI_UNSUPPORTED;
297}
298#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT */
299
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +0900300/**
301 * efi_update_capsule() - process information from operating system
302 * @capsule_header_array: Array of virtual address pointers
303 * @capsule_count: Number of pointers in capsule_header_array
304 * @scatter_gather_list: Array of physical address pointers
305 *
306 * This function implements the UpdateCapsule() runtime service.
307 *
308 * See the Unified Extensible Firmware Interface (UEFI) specification for
309 * details.
310 *
311 * Return: status code
312 */
313efi_status_t EFIAPI efi_update_capsule(
314 struct efi_capsule_header **capsule_header_array,
315 efi_uintn_t capsule_count,
316 u64 scatter_gather_list)
317{
318 struct efi_capsule_header *capsule;
319 unsigned int i;
320 efi_status_t ret;
321
322 EFI_ENTRY("%p, %lu, %llu\n", capsule_header_array, capsule_count,
323 scatter_gather_list);
324
325 if (!capsule_count) {
326 ret = EFI_INVALID_PARAMETER;
327 goto out;
328 }
329
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900330 ret = EFI_SUCCESS;
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +0900331 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
332 i++, capsule = *(++capsule_header_array)) {
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900333 /* sanity check */
334 if (capsule->header_size < sizeof(*capsule) ||
335 capsule->capsule_image_size < sizeof(*capsule)) {
336 log_err("EFI: A capsule has not enough data\n");
337 continue;
338 }
339
340 log_debug("Capsule[%d] (guid:%pUl)\n",
341 i, &capsule->capsule_guid);
342 if (!guidcmp(&capsule->capsule_guid,
343 &efi_guid_firmware_management_capsule_id)) {
344 ret = efi_capsule_update_firmware(capsule);
345 } else {
346 log_err("EFI: not support capsule type: %pUl\n",
347 &capsule->capsule_guid);
348 ret = EFI_UNSUPPORTED;
349 }
350
351 if (ret != EFI_SUCCESS)
352 goto out;
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +0900353 }
354out:
355 return EFI_EXIT(ret);
356}
357
358/**
359 * efi_query_capsule_caps() - check if capsule is supported
360 * @capsule_header_array: Array of virtual pointers
361 * @capsule_count: Number of pointers in capsule_header_array
362 * @maximum_capsule_size: Maximum capsule size
363 * @reset_type: Type of reset needed for capsule update
364 *
365 * This function implements the QueryCapsuleCapabilities() runtime service.
366 *
367 * See the Unified Extensible Firmware Interface (UEFI) specification for
368 * details.
369 *
370 * Return: status code
371 */
372efi_status_t EFIAPI efi_query_capsule_caps(
373 struct efi_capsule_header **capsule_header_array,
374 efi_uintn_t capsule_count,
375 u64 *maximum_capsule_size,
376 u32 *reset_type)
377{
378 struct efi_capsule_header *capsule __attribute__((unused));
379 unsigned int i;
380 efi_status_t ret;
381
382 EFI_ENTRY("%p, %lu, %p, %p\n", capsule_header_array, capsule_count,
383 maximum_capsule_size, reset_type);
384
385 if (!maximum_capsule_size) {
386 ret = EFI_INVALID_PARAMETER;
387 goto out;
388 }
389
390 *maximum_capsule_size = U64_MAX;
391 *reset_type = EFI_RESET_COLD;
392
393 ret = EFI_SUCCESS;
394 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
395 i++, capsule = *(++capsule_header_array)) {
396 /* TODO */
397 }
398out:
399 return EFI_EXIT(ret);
400}
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900401
402#ifdef CONFIG_EFI_CAPSULE_ON_DISK
403/**
404 * get_dp_device - retrieve a device path from boot variable
405 * @boot_var: Boot variable name
406 * @device_dp Device path
407 *
408 * Retrieve a device patch from boot variable, @boot_var.
409 *
410 * Return: status code
411 */
412static efi_status_t get_dp_device(u16 *boot_var,
413 struct efi_device_path **device_dp)
414{
415 void *buf = NULL;
416 efi_uintn_t size;
417 struct efi_load_option lo;
418 struct efi_device_path *file_dp;
419 efi_status_t ret;
420
421 size = 0;
422 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
423 NULL, &size, NULL, NULL);
424 if (ret == EFI_BUFFER_TOO_SMALL) {
425 buf = malloc(size);
426 if (!buf)
427 return EFI_OUT_OF_RESOURCES;
428 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
429 NULL, &size, buf, NULL);
430 }
431 if (ret != EFI_SUCCESS)
432 return ret;
433
434 efi_deserialize_load_option(&lo, buf, &size);
435
436 if (lo.attributes & LOAD_OPTION_ACTIVE) {
437 efi_dp_split_file_path(lo.file_path, device_dp, &file_dp);
438 efi_free_pool(file_dp);
439
440 ret = EFI_SUCCESS;
441 } else {
442 ret = EFI_NOT_FOUND;
443 }
444
445 free(buf);
446
447 return ret;
448}
449
450/**
451 * device_is_present_and_system_part - check if a device exists
452 * @dp Device path
453 *
454 * Check if a device pointed to by the device path, @dp, exists and is
455 * located in UEFI system partition.
456 *
457 * Return: true - yes, false - no
458 */
459static bool device_is_present_and_system_part(struct efi_device_path *dp)
460{
461 efi_handle_t handle;
462
463 handle = efi_dp_find_obj(dp, NULL);
464 if (!handle)
465 return false;
466
467 return efi_disk_is_system_part(handle);
468}
469
470/**
471 * find_boot_device - identify the boot device
472 *
473 * Identify the boot device from boot-related variables as UEFI
474 * specification describes and put its handle into bootdev_root.
475 *
476 * Return: status code
477 */
478static efi_status_t find_boot_device(void)
479{
480 char boot_var[9];
481 u16 boot_var16[9], *p, bootnext, *boot_order = NULL;
482 efi_uintn_t size;
483 int i, num;
484 struct efi_simple_file_system_protocol *volume;
485 struct efi_device_path *boot_dev = NULL;
486 efi_status_t ret;
487
488 /* find active boot device in BootNext */
489 bootnext = 0;
490 size = sizeof(bootnext);
491 ret = efi_get_variable_int(L"BootNext",
492 (efi_guid_t *)&efi_global_variable_guid,
493 NULL, &size, &bootnext, NULL);
494 if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
495 /* BootNext does exist here */
496 if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16)) {
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900497 log_err("BootNext must be 16-bit integer\n");
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900498 goto skip;
499 }
500 sprintf((char *)boot_var, "Boot%04X", bootnext);
501 p = boot_var16;
502 utf8_utf16_strcpy(&p, boot_var);
503
504 ret = get_dp_device(boot_var16, &boot_dev);
505 if (ret == EFI_SUCCESS) {
506 if (device_is_present_and_system_part(boot_dev)) {
507 goto out;
508 } else {
509 efi_free_pool(boot_dev);
510 boot_dev = NULL;
511 }
512 }
513 }
514
515skip:
516 /* find active boot device in BootOrder */
517 size = 0;
518 ret = efi_get_variable_int(L"BootOrder", &efi_global_variable_guid,
519 NULL, &size, NULL, NULL);
520 if (ret == EFI_BUFFER_TOO_SMALL) {
521 boot_order = malloc(size);
522 if (!boot_order) {
523 ret = EFI_OUT_OF_RESOURCES;
524 goto out;
525 }
526
527 ret = efi_get_variable_int(L"BootOrder",
528 &efi_global_variable_guid,
529 NULL, &size, boot_order, NULL);
530 }
531 if (ret != EFI_SUCCESS)
532 goto out;
533
534 /* check in higher order */
535 num = size / sizeof(u16);
536 for (i = 0; i < num; i++) {
537 sprintf((char *)boot_var, "Boot%04X", boot_order[i]);
538 p = boot_var16;
539 utf8_utf16_strcpy(&p, boot_var);
540 ret = get_dp_device(boot_var16, &boot_dev);
541 if (ret != EFI_SUCCESS)
542 continue;
543
544 if (device_is_present_and_system_part(boot_dev))
545 break;
546
547 efi_free_pool(boot_dev);
548 boot_dev = NULL;
549 }
550out:
551 if (boot_dev) {
552 u16 *path_str;
553
554 path_str = efi_dp_str(boot_dev);
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900555 log_debug("EFI Capsule: bootdev is %ls\n", path_str);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900556 efi_free_pool(path_str);
557
558 volume = efi_fs_from_path(boot_dev);
559 if (!volume)
560 ret = EFI_DEVICE_ERROR;
561 else
562 ret = EFI_CALL(volume->open_volume(volume,
563 &bootdev_root));
564 efi_free_pool(boot_dev);
565 } else {
566 ret = EFI_NOT_FOUND;
567 }
568 free(boot_order);
569
570 return ret;
571}
572
573/**
574 * efi_capsule_scan_dir - traverse a capsule directory in boot device
575 * @files: Array of file names
576 * @num: Number of elements in @files
577 *
578 * Traverse a capsule directory in boot device.
579 * Called by initialization code, and returns an array of capsule file
580 * names in @files.
581 *
582 * Return: status code
583 */
584static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num)
585{
586 struct efi_file_handle *dirh;
587 struct efi_file_info *dirent;
588 efi_uintn_t dirent_size, tmp_size;
589 unsigned int count;
590 u16 **tmp_files;
591 efi_status_t ret;
592
593 ret = find_boot_device();
594 if (ret == EFI_NOT_FOUND) {
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900595 log_debug("EFI Capsule: bootdev is not set\n");
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900596 *num = 0;
597 return EFI_SUCCESS;
598 } else if (ret != EFI_SUCCESS) {
599 return EFI_DEVICE_ERROR;
600 }
601
602 /* count capsule files */
603 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
604 EFI_CAPSULE_DIR,
605 EFI_FILE_MODE_READ, 0));
606 if (ret != EFI_SUCCESS) {
607 *num = 0;
608 return EFI_SUCCESS;
609 }
610
611 dirent_size = 256;
612 dirent = malloc(dirent_size);
613 if (!dirent)
614 return EFI_OUT_OF_RESOURCES;
615
616 count = 0;
617 while (1) {
618 tmp_size = dirent_size;
619 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
620 if (ret == EFI_BUFFER_TOO_SMALL) {
621 dirent = realloc(dirent, tmp_size);
622 if (!dirent) {
623 ret = EFI_OUT_OF_RESOURCES;
624 goto err;
625 }
626 dirent_size = tmp_size;
627 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
628 }
629 if (ret != EFI_SUCCESS)
630 goto err;
631 if (!tmp_size)
632 break;
633
634 if (!(dirent->attribute & EFI_FILE_DIRECTORY) &&
635 u16_strcmp(dirent->file_name, L".") &&
636 u16_strcmp(dirent->file_name, L".."))
637 count++;
638 }
639
640 ret = EFI_CALL((*dirh->setpos)(dirh, 0));
641 if (ret != EFI_SUCCESS)
642 goto err;
643
644 /* make a list */
645 tmp_files = malloc(count * sizeof(*files));
646 if (!tmp_files) {
647 ret = EFI_OUT_OF_RESOURCES;
648 goto err;
649 }
650
651 count = 0;
652 while (1) {
653 tmp_size = dirent_size;
654 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
655 if (ret != EFI_SUCCESS)
656 goto err;
657 if (!tmp_size)
658 break;
659
660 if (!(dirent->attribute & EFI_FILE_DIRECTORY) &&
661 u16_strcmp(dirent->file_name, L".") &&
662 u16_strcmp(dirent->file_name, L".."))
663 tmp_files[count++] = u16_strdup(dirent->file_name);
664 }
665 /* ignore an error */
666 EFI_CALL((*dirh->close)(dirh));
667
668 /* in ascii order */
669 /* FIXME: u16 version of strcasecmp */
670 qsort(tmp_files, count, sizeof(*tmp_files),
671 (int (*)(const void *, const void *))strcasecmp);
672 *files = tmp_files;
673 *num = count;
674 ret = EFI_SUCCESS;
675err:
676 free(dirent);
677
678 return ret;
679}
680
681/**
682 * efi_capsule_read_file - read in a capsule file
683 * @filename: File name
684 * @capsule: Pointer to buffer for capsule
685 *
686 * Read a capsule file and put its content in @capsule.
687 *
688 * Return: status code
689 */
690static efi_status_t efi_capsule_read_file(const u16 *filename,
691 struct efi_capsule_header **capsule)
692{
693 struct efi_file_handle *dirh, *fh;
694 struct efi_file_info *file_info = NULL;
695 struct efi_capsule_header *buf = NULL;
696 efi_uintn_t size;
697 efi_status_t ret;
698
699 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
700 EFI_CAPSULE_DIR,
701 EFI_FILE_MODE_READ, 0));
702 if (ret != EFI_SUCCESS)
703 return ret;
704 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
705 EFI_FILE_MODE_READ, 0));
706 /* ignore an error */
707 EFI_CALL((*dirh->close)(dirh));
708 if (ret != EFI_SUCCESS)
709 return ret;
710
711 /* file size */
712 size = 0;
713 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
714 &size, file_info));
715 if (ret == EFI_BUFFER_TOO_SMALL) {
716 file_info = malloc(size);
717 if (!file_info) {
718 ret = EFI_OUT_OF_RESOURCES;
719 goto err;
720 }
721 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
722 &size, file_info));
723 }
724 if (ret != EFI_SUCCESS)
725 goto err;
726 size = file_info->file_size;
727 free(file_info);
728 buf = malloc(size);
729 if (!buf) {
730 ret = EFI_OUT_OF_RESOURCES;
731 goto err;
732 }
733
734 /* fetch data */
735 ret = EFI_CALL((*fh->read)(fh, &size, buf));
736 if (ret == EFI_SUCCESS) {
737 if (size >= buf->capsule_image_size) {
738 *capsule = buf;
739 } else {
740 free(buf);
741 ret = EFI_INVALID_PARAMETER;
742 }
743 } else {
744 free(buf);
745 }
746err:
747 EFI_CALL((*fh->close)(fh));
748
749 return ret;
750}
751
752/**
753 * efi_capsule_delete_file - delete a capsule file
754 * @filename: File name
755 *
756 * Delete a capsule file from capsule directory.
757 *
758 * Return: status code
759 */
760static efi_status_t efi_capsule_delete_file(const u16 *filename)
761{
762 struct efi_file_handle *dirh, *fh;
763 efi_status_t ret;
764
765 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
766 EFI_CAPSULE_DIR,
767 EFI_FILE_MODE_READ, 0));
768 if (ret != EFI_SUCCESS)
769 return ret;
770 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
771 EFI_FILE_MODE_READ, 0));
772 /* ignore an error */
773 EFI_CALL((*dirh->close)(dirh));
774
775 ret = EFI_CALL((*fh->delete)(fh));
776
777 return ret;
778}
779
780/**
781 * efi_capsule_scan_done - reset a scan help function
782 *
783 * Reset a scan help function
784 */
785static void efi_capsule_scan_done(void)
786{
787 EFI_CALL((*bootdev_root->close)(bootdev_root));
788 bootdev_root = NULL;
789}
790
791/**
792 * arch_efi_load_capsule_drivers - initialize capsule drivers
793 *
794 * Architecture or board specific initialization routine
795 *
796 * Return: status code
797 */
798efi_status_t __weak arch_efi_load_capsule_drivers(void)
799{
800 return EFI_SUCCESS;
801}
802
803/**
804 * efi_launch_capsule - launch capsules
805 *
806 * Launch all the capsules in system at boot time.
807 * Called by efi init code
808 *
809 * Return: status codde
810 */
811efi_status_t efi_launch_capsules(void)
812{
813 u64 os_indications;
814 efi_uintn_t size;
815 struct efi_capsule_header *capsule = NULL;
816 u16 **files;
817 unsigned int nfiles, index, i;
818 u16 variable_name16[12];
819 efi_status_t ret;
820
821 size = sizeof(os_indications);
822 ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
823 NULL, &size, &os_indications, NULL);
824 if (ret != EFI_SUCCESS ||
825 !(os_indications
826 & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED))
827 return EFI_SUCCESS;
828
829 index = get_last_capsule();
830
831 /* Load capsule drivers */
832 ret = arch_efi_load_capsule_drivers();
833 if (ret != EFI_SUCCESS)
834 return ret;
835
836 /*
837 * Find capsules on disk.
838 * All the capsules are collected at the beginning because
839 * capsule files will be removed instantly.
840 */
841 nfiles = 0;
842 files = NULL;
843 ret = efi_capsule_scan_dir(&files, &nfiles);
844 if (ret != EFI_SUCCESS)
845 return ret;
846 if (!nfiles)
847 return EFI_SUCCESS;
848
849 /* Launch capsules */
850 for (i = 0, ++index; i < nfiles; i++, index++) {
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900851 log_debug("capsule from %ls ...\n", files[i]);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900852 if (index > 0xffff)
853 index = 0;
854 ret = efi_capsule_read_file(files[i], &capsule);
855 if (ret == EFI_SUCCESS) {
856 ret = EFI_CALL(efi_update_capsule(&capsule, 1, 0));
857 if (ret != EFI_SUCCESS)
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900858 log_err("EFI Capsule update failed at %ls\n",
859 files[i]);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900860
861 free(capsule);
862 } else {
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900863 log_err("EFI: reading capsule failed: %ls\n", files[i]);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900864 }
865 /* create CapsuleXXXX */
866 set_capsule_result(index, capsule, ret);
867
868 /* delete a capsule either in case of success or failure */
869 ret = efi_capsule_delete_file(files[i]);
870 if (ret != EFI_SUCCESS)
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900871 log_err("EFI: deleting a capsule file failed: %ls\n",
872 files[i]);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900873 }
874 efi_capsule_scan_done();
875
876 for (i = 0; i < nfiles; i++)
877 free(files[i]);
878 free(files);
879
880 /* CapsuleLast */
881 efi_create_indexed_name(variable_name16, "Capsule", index - 1);
882 efi_set_variable_int(L"CapsuleLast", &efi_guid_capsule_report,
883 EFI_VARIABLE_READ_ONLY |
884 EFI_VARIABLE_NON_VOLATILE |
885 EFI_VARIABLE_BOOTSERVICE_ACCESS |
886 EFI_VARIABLE_RUNTIME_ACCESS,
887 22, variable_name16, false);
888
889 return ret;
890}
891#endif /* CONFIG_EFI_CAPSULE_ON_DISK */