blob: e815fa06c8bd3ff5fc182feb624342ccefa6bebc [file] [log] [blame]
Tom Rinif739fcd2018-05-07 17:02:21 -04001// SPDX-License-Identifier: GPL-2.0+
Rob Clark9975fe92017-09-13 18:05:38 -04002/*
Heinrich Schuchardte1fec152018-10-18 21:51:38 +02003 * EFI boot manager
Rob Clark9975fe92017-09-13 18:05:38 -04004 *
5 * Copyright (c) 2017 Rob Clark
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +09006 * For the code moved from cmd/bootefi.c
7 * Copyright (c) 2016 Alexander Graf
Rob Clark9975fe92017-09-13 18:05:38 -04008 */
9
Heinrich Schuchardt7a373e52020-05-31 10:07:31 +020010#define LOG_CATEGORY LOGC_EFI
11
Masahisa Kojimad7d07a82023-11-10 13:25:40 +090012#include <blk.h>
13#include <blkmap.h>
Rob Clark9975fe92017-09-13 18:05:38 -040014#include <common.h>
15#include <charset.h>
Masahisa Kojimad7d07a82023-11-10 13:25:40 +090016#include <dm.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060017#include <log.h>
Rob Clark9975fe92017-09-13 18:05:38 -040018#include <malloc.h>
Masahisa Kojimad7d07a82023-11-10 13:25:40 +090019#include <net.h>
AKASHI Takahiro4e65ca02022-04-28 17:09:39 +090020#include <efi_default_filename.h>
Rob Clark9975fe92017-09-13 18:05:38 -040021#include <efi_loader.h>
Heinrich Schuchardtdda8c712020-06-24 19:09:18 +020022#include <efi_variable.h>
AKASHI Takahiro1a82b342018-11-05 18:06:41 +090023#include <asm/unaligned.h>
Rob Clark9975fe92017-09-13 18:05:38 -040024
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +090025/* TODO: temporarily added here; clean up later */
26#include <bootm.h>
27#include <efi_selftest.h>
28#include <env.h>
29#include <mapmem.h>
30#include <asm/global_data.h>
31#include <linux/libfdt.h>
32#include <linux/libfdt_env.h>
33
34DECLARE_GLOBAL_DATA_PTR;
35
Rob Clark9975fe92017-09-13 18:05:38 -040036static const struct efi_boot_services *bs;
37static const struct efi_runtime_services *rs;
38
Masahisa Kojimad7d07a82023-11-10 13:25:40 +090039/**
40 * struct uridp_context - uri device path resource
41 *
42 * @image_size: image size
43 * @image_addr: image address
44 * @loaded_dp: pointer to loaded device path
45 * @ramdisk_blk_dev: pointer to the ramdisk blk device
46 * @mem_handle: efi_handle to the loaded PE-COFF image
47 */
48struct uridp_context {
49 ulong image_size;
50 ulong image_addr;
51 struct efi_device_path *loaded_dp;
52 struct udevice *ramdisk_blk_dev;
53 efi_handle_t mem_handle;
54};
55
Masahisa Kojima87d79142022-09-12 17:33:50 +090056const efi_guid_t efi_guid_bootmenu_auto_generated =
57 EFICONFIG_AUTO_GENERATED_ENTRY_GUID;
58
Rob Clark9975fe92017-09-13 18:05:38 -040059/*
60 * bootmgr implements the logic of trying to find a payload to boot
61 * based on the BootOrder + BootXXXX variables, and then loading it.
62 *
63 * TODO detecting a special key held (f9?) and displaying a boot menu
64 * like you would get on a PC would be clever.
65 *
66 * TODO if we had a way to write and persist variables after the OS
67 * has started, we'd also want to check OsIndications to see if we
68 * should do normal or recovery boot.
69 */
70
Heinrich Schuchardt1064d042020-08-07 17:47:13 +020071/**
AKASHI Takahiro4e65ca02022-04-28 17:09:39 +090072 * expand_media_path() - expand a device path for default file name
73 * @device_path: device path to check against
74 *
75 * If @device_path is a media or disk partition which houses a file
76 * system, this function returns a full device path which contains
77 * an architecture-specific default file name for removable media.
78 *
79 * Return: a newly allocated device path
80 */
81static
82struct efi_device_path *expand_media_path(struct efi_device_path *device_path)
83{
Heinrich Schuchardtc7c0ca32023-05-13 10:36:21 +020084 struct efi_device_path *rem, *full_path;
AKASHI Takahiro4e65ca02022-04-28 17:09:39 +090085 efi_handle_t handle;
AKASHI Takahiro4e65ca02022-04-28 17:09:39 +090086
87 if (!device_path)
88 return NULL;
89
90 /*
91 * If device_path is a (removable) media or partition which provides
92 * simple file system protocol, append a default file name to support
93 * booting from removable media.
94 */
Heinrich Schuchardtc7c0ca32023-05-13 10:36:21 +020095 handle = efi_dp_find_obj(device_path,
96 &efi_simple_file_system_protocol_guid, &rem);
Heinrich Schuchardt72fa9cd2022-06-11 05:22:08 +000097 if (handle) {
Heinrich Schuchardt178667b2022-06-11 05:22:07 +000098 if (rem->type == DEVICE_PATH_TYPE_END) {
Heinrich Schuchardtc7c0ca32023-05-13 10:36:21 +020099 full_path = efi_dp_from_file(device_path,
100 "/EFI/BOOT/" BOOTEFI_NAME);
AKASHI Takahiro4e65ca02022-04-28 17:09:39 +0900101 } else {
102 full_path = efi_dp_dup(device_path);
103 }
104 } else {
105 full_path = efi_dp_dup(device_path);
106 }
107
108 return full_path;
109}
110
111/**
AKASHI Takahiro57ad6242022-05-12 11:29:02 +0900112 * try_load_from_file_path() - try to load a file
113 *
114 * Given a file media path iterate through a list of handles and try to
115 * to load the file from each of them until the first success.
116 *
117 * @fs_handles: array of handles with the simple file protocol
118 * @num: number of handles in fs_handles
119 * @fp: file path to open
120 * @handle: on return pointer to handle for loaded image
121 * @removable: if true only consider removable media, else only non-removable
122 */
123static efi_status_t try_load_from_file_path(efi_handle_t *fs_handles,
124 efi_uintn_t num,
125 struct efi_device_path *fp,
126 efi_handle_t *handle,
127 bool removable)
128{
129 struct efi_handler *handler;
130 struct efi_device_path *dp;
131 int i;
132 efi_status_t ret;
133
134 for (i = 0; i < num; i++) {
135 if (removable != efi_disk_is_removable(fs_handles[i]))
136 continue;
137
138 ret = efi_search_protocol(fs_handles[i], &efi_guid_device_path,
139 &handler);
140 if (ret != EFI_SUCCESS)
141 continue;
142
143 dp = handler->protocol_interface;
144 if (!dp)
145 continue;
146
147 dp = efi_dp_append(dp, fp);
148 if (!dp)
149 continue;
150
151 ret = EFI_CALL(efi_load_image(true, efi_root, dp, NULL, 0,
152 handle));
153 efi_free_pool(dp);
154 if (ret == EFI_SUCCESS)
155 return ret;
156 }
157
158 return EFI_NOT_FOUND;
159}
160
161/**
162 * try_load_from_short_path
163 * @fp: file path
164 * @handle: pointer to handle for newly installed image
165 *
166 * Enumerate all the devices which support file system operations,
167 * prepend its media device path to the file path, @fp, and
168 * try to load the file.
169 * This function should be called when handling a short-form path
170 * which is starting with a file device path.
171 *
172 * Return: status code
173 */
174static efi_status_t try_load_from_short_path(struct efi_device_path *fp,
175 efi_handle_t *handle)
176{
177 efi_handle_t *fs_handles;
178 efi_uintn_t num;
179 efi_status_t ret;
180
181 ret = EFI_CALL(efi_locate_handle_buffer(
182 BY_PROTOCOL,
183 &efi_simple_file_system_protocol_guid,
184 NULL,
185 &num, &fs_handles));
186 if (ret != EFI_SUCCESS)
187 return ret;
188 if (!num)
189 return EFI_NOT_FOUND;
190
191 /* removable media first */
192 ret = try_load_from_file_path(fs_handles, num, fp, handle, true);
193 if (ret == EFI_SUCCESS)
194 goto out;
195
196 /* fixed media */
197 ret = try_load_from_file_path(fs_handles, num, fp, handle, false);
198 if (ret == EFI_SUCCESS)
199 goto out;
200
201out:
202 return ret;
203}
204
205/**
Masahisa Kojimad7d07a82023-11-10 13:25:40 +0900206 * mount_image() - mount the image with blkmap
207 *
208 * @lo_label: u16 label string of load option
209 * @addr: image address
210 * @size: image size
211 * Return: pointer to the UCLASS_BLK udevice, NULL if failed
212 */
213static struct udevice *mount_image(u16 *lo_label, ulong addr, ulong size)
214{
215 int err;
216 struct blkmap *bm;
217 struct udevice *bm_dev;
218 char *label = NULL, *p;
219
220 label = efi_alloc(utf16_utf8_strlen(lo_label) + 1);
221 if (!label)
222 return NULL;
223
224 p = label;
225 utf16_utf8_strcpy(&p, lo_label);
226 err = blkmap_create_ramdisk(label, addr, size, &bm_dev);
227 if (err) {
228 efi_free_pool(label);
229 return NULL;
230 }
231 bm = dev_get_plat(bm_dev);
232
233 efi_free_pool(label);
234
235 return bm->blk;
236}
237
238/**
239 * search_default_file() - search default file
240 *
241 * @dev: pointer to the UCLASS_BLK or UCLASS_PARTITION udevice
242 * @loaded_dp: pointer to default file device path
243 * Return: status code
244 */
245static efi_status_t search_default_file(struct udevice *dev,
246 struct efi_device_path **loaded_dp)
247{
248 efi_status_t ret;
249 efi_handle_t handle;
250 u16 *default_file_name = NULL;
251 struct efi_file_handle *root, *f;
252 struct efi_device_path *dp = NULL, *fp = NULL;
253 struct efi_simple_file_system_protocol *file_system;
254 struct efi_device_path *device_path, *full_path = NULL;
255
256 if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) {
257 log_warning("DM_TAG_EFI not found\n");
258 return EFI_INVALID_PARAMETER;
259 }
260
261 ret = EFI_CALL(bs->open_protocol(handle, &efi_guid_device_path,
262 (void **)&device_path, efi_root, NULL,
263 EFI_OPEN_PROTOCOL_GET_PROTOCOL));
264 if (ret != EFI_SUCCESS)
265 return ret;
266
267 ret = EFI_CALL(bs->open_protocol(handle, &efi_simple_file_system_protocol_guid,
268 (void **)&file_system, efi_root, NULL,
269 EFI_OPEN_PROTOCOL_GET_PROTOCOL));
270 if (ret != EFI_SUCCESS)
271 return ret;
272
273 ret = EFI_CALL(file_system->open_volume(file_system, &root));
274 if (ret != EFI_SUCCESS)
275 return ret;
276
277 full_path = expand_media_path(device_path);
278 ret = efi_dp_split_file_path(full_path, &dp, &fp);
279 if (ret != EFI_SUCCESS)
280 goto err;
281
282 default_file_name = efi_dp_str(fp);
283 efi_free_pool(dp);
284 efi_free_pool(fp);
285 if (!default_file_name) {
286 ret = EFI_OUT_OF_RESOURCES;
287 goto err;
288 }
289
290 ret = EFI_CALL(root->open(root, &f, default_file_name,
291 EFI_FILE_MODE_READ, 0));
292 efi_free_pool(default_file_name);
293 if (ret != EFI_SUCCESS)
294 goto err;
295
296 EFI_CALL(f->close(f));
297 EFI_CALL(root->close(root));
298
299 *loaded_dp = full_path;
300
301 return EFI_SUCCESS;
302
303err:
304 EFI_CALL(root->close(root));
305 efi_free_pool(full_path);
306
307 return ret;
308}
309
310/**
311 * check_disk_has_default_file() - load the default file
312 *
313 * @blk: pointer to the UCLASS_BLK udevice
314 * @dp: pointer to default file device path
315 * Return: status code
316 */
317static efi_status_t check_disk_has_default_file(struct udevice *blk,
318 struct efi_device_path **dp)
319{
320 efi_status_t ret;
321 struct udevice *partition;
322
323 /* image that has no partition table but a file system */
324 ret = search_default_file(blk, dp);
325 if (ret == EFI_SUCCESS)
326 return ret;
327
328 /* try the partitions */
329 device_foreach_child(partition, blk) {
330 enum uclass_id id;
331
332 id = device_get_uclass_id(partition);
333 if (id != UCLASS_PARTITION)
334 continue;
335
336 ret = search_default_file(partition, dp);
337 if (ret == EFI_SUCCESS)
338 return ret;
339 }
340
341 return EFI_NOT_FOUND;
342}
343
344/**
345 * prepare_loaded_image() - prepare ramdisk for downloaded image
346 *
347 * @label: label of load option
348 * @addr: image address
349 * @size: image size
350 * @dp: pointer to default file device path
351 * @blk: pointer to created blk udevice
352 * Return: status code
353 */
354static efi_status_t prepare_loaded_image(u16 *label, ulong addr, ulong size,
355 struct efi_device_path **dp,
356 struct udevice **blk)
357{
358 efi_status_t ret;
359 struct udevice *ramdisk_blk;
360
361 ramdisk_blk = mount_image(label, addr, size);
362 if (!ramdisk_blk)
363 return EFI_LOAD_ERROR;
364
365 ret = check_disk_has_default_file(ramdisk_blk, dp);
366 if (ret != EFI_SUCCESS) {
367 log_info("Cannot boot from downloaded image\n");
368 goto err;
369 }
370
371 /*
372 * TODO: expose the ramdisk to OS.
373 * Need to pass the ramdisk information by the architecture-specific
374 * methods such as 'pmem' device-tree node.
375 */
376 ret = efi_add_memory_map(addr, size, EFI_RESERVED_MEMORY_TYPE);
377 if (ret != EFI_SUCCESS) {
378 log_err("Memory reservation failed\n");
379 goto err;
380 }
381
382 *blk = ramdisk_blk;
383
384 return EFI_SUCCESS;
385
386err:
387 if (blkmap_destroy(ramdisk_blk->parent))
388 log_err("Destroying blkmap failed\n");
389
390 return ret;
391}
392
393/**
394 * efi_bootmgr_release_uridp_resource() - cleanup uri device path resource
395 *
396 * @ctx: event context
397 * Return: status code
398 */
399efi_status_t efi_bootmgr_release_uridp_resource(struct uridp_context *ctx)
400{
401 efi_status_t ret = EFI_SUCCESS;
402
403 if (!ctx)
404 return ret;
405
406 /* cleanup for iso or img image */
407 if (ctx->ramdisk_blk_dev) {
408 ret = efi_add_memory_map(ctx->image_addr, ctx->image_size,
409 EFI_CONVENTIONAL_MEMORY);
410 if (ret != EFI_SUCCESS)
411 log_err("Reclaiming memory failed\n");
412
413 if (blkmap_destroy(ctx->ramdisk_blk_dev->parent)) {
414 log_err("Destroying blkmap failed\n");
415 ret = EFI_DEVICE_ERROR;
416 }
417 }
418
419 /* cleanup for PE-COFF image */
420 if (ctx->mem_handle) {
421 ret = efi_uninstall_multiple_protocol_interfaces(
422 ctx->mem_handle, &efi_guid_device_path, ctx->loaded_dp,
423 NULL);
424 if (ret != EFI_SUCCESS)
425 log_err("Uninstall device_path protocol failed\n");
426 }
427
428 efi_free_pool(ctx->loaded_dp);
429 free(ctx);
430
431 return ret;
432}
433
434/**
435 * efi_bootmgr_image_return_notify() - return to efibootmgr callback
436 *
437 * @event: the event for which this notification function is registered
438 * @context: event context
439 */
440static void EFIAPI efi_bootmgr_image_return_notify(struct efi_event *event,
441 void *context)
442{
443 efi_status_t ret;
444
445 EFI_ENTRY("%p, %p", event, context);
446 ret = efi_bootmgr_release_uridp_resource(context);
447 EFI_EXIT(ret);
448}
449
450/**
451 * try_load_from_uri_path() - Handle the URI device path
452 *
453 * @uridp: uri device path
454 * @lo_label: label of load option
455 * @handle: pointer to handle for newly installed image
456 * Return: status code
457 */
458static efi_status_t try_load_from_uri_path(struct efi_device_path_uri *uridp,
459 u16 *lo_label,
460 efi_handle_t *handle)
461{
462 char *s;
463 int err;
464 int uri_len;
465 efi_status_t ret;
466 void *source_buffer;
467 efi_uintn_t source_size;
468 struct uridp_context *ctx;
469 struct udevice *blk = NULL;
470 struct efi_event *event = NULL;
471 efi_handle_t mem_handle = NULL;
472 struct efi_device_path *loaded_dp;
473 static ulong image_size, image_addr;
474
475 ctx = calloc(1, sizeof(struct uridp_context));
476 if (!ctx)
477 return EFI_OUT_OF_RESOURCES;
478
479 s = env_get("loadaddr");
480 if (!s) {
481 log_err("Error: loadaddr is not set\n");
482 ret = EFI_INVALID_PARAMETER;
483 goto err;
484 }
485
486 image_addr = hextoul(s, NULL);
487 err = wget_with_dns(image_addr, uridp->uri);
488 if (err < 0) {
489 ret = EFI_INVALID_PARAMETER;
490 goto err;
491 }
492
493 image_size = env_get_hex("filesize", 0);
494 if (!image_size) {
495 ret = EFI_INVALID_PARAMETER;
496 goto err;
497 }
498
499 /*
500 * If the file extension is ".iso" or ".img", mount it and try to load
501 * the default file.
502 * If the file is PE-COFF image, load the downloaded file.
503 */
504 uri_len = strlen(uridp->uri);
505 if (!strncmp(&uridp->uri[uri_len - 4], ".iso", 4) ||
506 !strncmp(&uridp->uri[uri_len - 4], ".img", 4)) {
507 ret = prepare_loaded_image(lo_label, image_addr, image_size,
508 &loaded_dp, &blk);
509 if (ret != EFI_SUCCESS)
510 goto err;
511
512 source_buffer = NULL;
513 source_size = 0;
514 } else if (efi_check_pe((void *)image_addr, image_size, NULL) == EFI_SUCCESS) {
515 /*
516 * loaded_dp must exist until efi application returns,
517 * will be freed in return_to_efibootmgr event callback.
518 */
519 loaded_dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
520 (uintptr_t)image_addr, image_size);
521 ret = efi_install_multiple_protocol_interfaces(
522 &mem_handle, &efi_guid_device_path, loaded_dp, NULL);
523 if (ret != EFI_SUCCESS)
524 goto err;
525
526 source_buffer = (void *)image_addr;
527 source_size = image_size;
528 } else {
529 log_err("Error: file type is not supported\n");
530 ret = EFI_UNSUPPORTED;
531 goto err;
532 }
533
534 ctx->image_size = image_size;
535 ctx->image_addr = image_addr;
536 ctx->loaded_dp = loaded_dp;
537 ctx->ramdisk_blk_dev = blk;
538 ctx->mem_handle = mem_handle;
539
540 ret = EFI_CALL(efi_load_image(false, efi_root, loaded_dp, source_buffer,
541 source_size, handle));
542 if (ret != EFI_SUCCESS)
543 goto err;
544
545 /* create event for cleanup when the image returns or error occurs */
546 ret = efi_create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
547 efi_bootmgr_image_return_notify, ctx,
548 &efi_guid_event_group_return_to_efibootmgr,
549 &event);
550 if (ret != EFI_SUCCESS) {
551 log_err("Creating event failed\n");
552 goto err;
553 }
554
555 return ret;
556
557err:
558 efi_bootmgr_release_uridp_resource(ctx);
559
560 return ret;
561}
562
563/**
Heinrich Schuchardt15621aa2019-07-14 13:20:28 +0200564 * try_load_entry() - try to load image for boot option
565 *
Rob Clark9975fe92017-09-13 18:05:38 -0400566 * Attempt to load load-option number 'n', returning device_path and file_path
Heinrich Schuchardt15621aa2019-07-14 13:20:28 +0200567 * if successful. This checks that the EFI_LOAD_OPTION is active (enabled)
Rob Clark9975fe92017-09-13 18:05:38 -0400568 * and that the specified file to boot exists.
Heinrich Schuchardt15621aa2019-07-14 13:20:28 +0200569 *
Heinrich Schuchardt0ad64002020-08-07 17:49:39 +0200570 * @n: number of the boot option, e.g. 0x0a13 for Boot0A13
571 * @handle: on return handle for the newly installed image
572 * @load_options: load options set on the loaded image protocol
573 * Return: status code
Rob Clark9975fe92017-09-13 18:05:38 -0400574 */
Heinrich Schuchardt0ad64002020-08-07 17:49:39 +0200575static efi_status_t try_load_entry(u16 n, efi_handle_t *handle,
576 void **load_options)
Rob Clark9975fe92017-09-13 18:05:38 -0400577{
AKASHI Takahiro1a82b342018-11-05 18:06:41 +0900578 struct efi_load_option lo;
Heinrich Schuchardt4f419962022-04-25 23:35:01 +0200579 u16 varname[9];
AKASHI Takahiro6b95b382019-04-19 12:22:35 +0900580 void *load_option;
Heinrich Schuchardt45c66f92018-05-17 07:57:05 +0200581 efi_uintn_t size;
AKASHI Takahiro6b95b382019-04-19 12:22:35 +0900582 efi_status_t ret;
Rob Clark9975fe92017-09-13 18:05:38 -0400583
Heinrich Schuchardt4f419962022-04-25 23:35:01 +0200584 efi_create_indexed_name(varname, sizeof(varname), "Boot", n);
Rob Clark9975fe92017-09-13 18:05:38 -0400585
Ilias Apalodimasf4dc1bc2021-03-27 10:56:07 +0200586 load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
Rob Clark9975fe92017-09-13 18:05:38 -0400587 if (!load_option)
AKASHI Takahiro6b95b382019-04-19 12:22:35 +0900588 return EFI_LOAD_ERROR;
Rob Clark9975fe92017-09-13 18:05:38 -0400589
Heinrich Schuchardt0e69bcf2020-05-31 22:46:09 +0200590 ret = efi_deserialize_load_option(&lo, load_option, &size);
591 if (ret != EFI_SUCCESS) {
592 log_warning("Invalid load option for %ls\n", varname);
593 goto error;
594 }
Rob Clark9975fe92017-09-13 18:05:38 -0400595
596 if (lo.attributes & LOAD_OPTION_ACTIVE) {
AKASHI Takahiro4e65ca02022-04-28 17:09:39 +0900597 struct efi_device_path *file_path;
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900598 u32 attributes;
Rob Clark9975fe92017-09-13 18:05:38 -0400599
Heinrich Schuchardt7ea79e52022-04-29 07:15:04 +0200600 log_debug("trying to load \"%ls\" from %pD\n", lo.label,
601 lo.file_path);
Rob Clark9975fe92017-09-13 18:05:38 -0400602
AKASHI Takahiro57ad6242022-05-12 11:29:02 +0900603 if (EFI_DP_TYPE(lo.file_path, MEDIA_DEVICE, FILE_PATH)) {
604 /* file_path doesn't contain a device path */
605 ret = try_load_from_short_path(lo.file_path, handle);
Masahisa Kojimad7d07a82023-11-10 13:25:40 +0900606 } else if (EFI_DP_TYPE(lo.file_path, MESSAGING_DEVICE, MSG_URI)) {
607 if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT))
608 ret = try_load_from_uri_path(
609 (struct efi_device_path_uri *)lo.file_path,
610 lo.label, handle);
611 else
612 ret = EFI_LOAD_ERROR;
AKASHI Takahiro57ad6242022-05-12 11:29:02 +0900613 } else {
614 file_path = expand_media_path(lo.file_path);
615 ret = EFI_CALL(efi_load_image(true, efi_root, file_path,
616 NULL, 0, handle));
617 efi_free_pool(file_path);
618 }
AKASHI Takahiro94e6e552019-05-29 20:54:25 +0200619 if (ret != EFI_SUCCESS) {
Heinrich Schuchardt7a373e52020-05-31 10:07:31 +0200620 log_warning("Loading %ls '%ls' failed\n",
621 varname, lo.label);
Rob Clark9975fe92017-09-13 18:05:38 -0400622 goto error;
AKASHI Takahiro94e6e552019-05-29 20:54:25 +0200623 }
Rob Clark9975fe92017-09-13 18:05:38 -0400624
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900625 attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
626 EFI_VARIABLE_RUNTIME_ACCESS;
Simon Glass156ccbc2022-01-23 12:55:12 -0700627 ret = efi_set_variable_int(u"BootCurrent",
Heinrich Schuchardtdda8c712020-06-24 19:09:18 +0200628 &efi_global_variable_guid,
Heinrich Schuchardt0ad64002020-08-07 17:49:39 +0200629 attributes, sizeof(n), &n, false);
Ilias Apalodimas53f6a5a2021-03-17 21:55:00 +0200630 if (ret != EFI_SUCCESS)
631 goto unload;
632 /* try to register load file2 for initrd's */
633 if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) {
634 ret = efi_initrd_register();
635 if (ret != EFI_SUCCESS)
636 goto unload;
AKASHI Takahiro6b95b382019-04-19 12:22:35 +0900637 }
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900638
Heinrich Schuchardt7a373e52020-05-31 10:07:31 +0200639 log_info("Booting: %ls\n", lo.label);
AKASHI Takahiro6b95b382019-04-19 12:22:35 +0900640 } else {
641 ret = EFI_LOAD_ERROR;
Rob Clark9975fe92017-09-13 18:05:38 -0400642 }
643
Heinrich Schuchardt0ad64002020-08-07 17:49:39 +0200644 /* Set load options */
Masahisa Kojimac416f1c2022-09-12 17:33:54 +0900645 if (size >= sizeof(efi_guid_t) &&
646 !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated))
647 size = 0;
648
Heinrich Schuchardt0ad64002020-08-07 17:49:39 +0200649 if (size) {
650 *load_options = malloc(size);
651 if (!*load_options) {
652 ret = EFI_OUT_OF_RESOURCES;
653 goto error;
654 }
655 memcpy(*load_options, lo.optional_data, size);
656 ret = efi_set_load_options(*handle, size, *load_options);
657 } else {
Heinrich Schuchardte4343112020-12-27 15:46:00 +0100658 *load_options = NULL;
Heinrich Schuchardt0ad64002020-08-07 17:49:39 +0200659 }
660
Rob Clark9975fe92017-09-13 18:05:38 -0400661error:
662 free(load_option);
663
AKASHI Takahiro6b95b382019-04-19 12:22:35 +0900664 return ret;
Ilias Apalodimas53f6a5a2021-03-17 21:55:00 +0200665
666unload:
667 if (EFI_CALL(efi_unload_image(*handle)) != EFI_SUCCESS)
668 log_err("Unloading image failed\n");
669 free(load_option);
670
671 return ret;
Rob Clark9975fe92017-09-13 18:05:38 -0400672}
673
Heinrich Schuchardt15621aa2019-07-14 13:20:28 +0200674/**
675 * efi_bootmgr_load() - try to load from BootNext or BootOrder
676 *
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900677 * Attempt to load from BootNext or in the order specified by BootOrder
678 * EFI variable, the available load-options, finding and returning
679 * the first one that can be loaded successfully.
Heinrich Schuchardt15621aa2019-07-14 13:20:28 +0200680 *
Heinrich Schuchardt0ad64002020-08-07 17:49:39 +0200681 * @handle: on return handle for the newly installed image
682 * @load_options: load options set on the loaded image protocol
683 * Return: status code
Rob Clark9975fe92017-09-13 18:05:38 -0400684 */
Heinrich Schuchardt0ad64002020-08-07 17:49:39 +0200685efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options)
Rob Clark9975fe92017-09-13 18:05:38 -0400686{
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900687 u16 bootnext, *bootorder;
Heinrich Schuchardt45c66f92018-05-17 07:57:05 +0200688 efi_uintn_t size;
Rob Clark9975fe92017-09-13 18:05:38 -0400689 int i, num;
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900690 efi_status_t ret;
Rob Clark9975fe92017-09-13 18:05:38 -0400691
Rob Clark9975fe92017-09-13 18:05:38 -0400692 bs = systab.boottime;
693 rs = systab.runtime;
694
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900695 /* BootNext */
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900696 size = sizeof(bootnext);
Simon Glass156ccbc2022-01-23 12:55:12 -0700697 ret = efi_get_variable_int(u"BootNext",
Heinrich Schuchardtdda8c712020-06-24 19:09:18 +0200698 &efi_global_variable_guid,
699 NULL, &size, &bootnext, NULL);
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900700 if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
701 /* BootNext does exist here */
702 if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16))
Heinrich Schuchardt7a373e52020-05-31 10:07:31 +0200703 log_err("BootNext must be 16-bit integer\n");
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900704
705 /* delete BootNext */
Simon Glass156ccbc2022-01-23 12:55:12 -0700706 ret = efi_set_variable_int(u"BootNext",
Heinrich Schuchardtdda8c712020-06-24 19:09:18 +0200707 &efi_global_variable_guid,
708 0, 0, NULL, false);
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900709
710 /* load BootNext */
711 if (ret == EFI_SUCCESS) {
712 if (size == sizeof(u16)) {
Heinrich Schuchardt0ad64002020-08-07 17:49:39 +0200713 ret = try_load_entry(bootnext, handle,
714 load_options);
AKASHI Takahiro6b95b382019-04-19 12:22:35 +0900715 if (ret == EFI_SUCCESS)
716 return ret;
Heinrich Schuchardt7a373e52020-05-31 10:07:31 +0200717 log_warning(
718 "Loading from BootNext failed, falling back to BootOrder\n");
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900719 }
720 } else {
Heinrich Schuchardt7a373e52020-05-31 10:07:31 +0200721 log_err("Deleting BootNext failed\n");
AKASHI Takahiro37279ad2019-03-20 09:07:55 +0900722 }
723 }
724
725 /* BootOrder */
Simon Glass156ccbc2022-01-23 12:55:12 -0700726 bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
Heinrich Schuchardt33e44972019-02-24 04:44:48 +0100727 if (!bootorder) {
Heinrich Schuchardt7a373e52020-05-31 10:07:31 +0200728 log_info("BootOrder not defined\n");
AKASHI Takahiro6b95b382019-04-19 12:22:35 +0900729 ret = EFI_NOT_FOUND;
Rob Clark9975fe92017-09-13 18:05:38 -0400730 goto error;
Heinrich Schuchardt33e44972019-02-24 04:44:48 +0100731 }
Rob Clark9975fe92017-09-13 18:05:38 -0400732
733 num = size / sizeof(uint16_t);
734 for (i = 0; i < num; i++) {
Heinrich Schuchardt7ea79e52022-04-29 07:15:04 +0200735 log_debug("trying to load Boot%04X\n", bootorder[i]);
Heinrich Schuchardt0ad64002020-08-07 17:49:39 +0200736 ret = try_load_entry(bootorder[i], handle, load_options);
AKASHI Takahiro6b95b382019-04-19 12:22:35 +0900737 if (ret == EFI_SUCCESS)
Rob Clark9975fe92017-09-13 18:05:38 -0400738 break;
739 }
740
741 free(bootorder);
742
743error:
AKASHI Takahiro6b95b382019-04-19 12:22:35 +0900744 return ret;
Rob Clark9975fe92017-09-13 18:05:38 -0400745}
Raymond Mao339b5272023-06-19 14:22:58 -0700746
747/**
748 * efi_bootmgr_enumerate_boot_option() - enumerate the possible bootable media
749 *
750 * @opt: pointer to the media boot option structure
751 * @volume_handles: pointer to the efi handles
752 * @count: number of efi handle
753 * Return: status code
754 */
755static efi_status_t efi_bootmgr_enumerate_boot_option(struct eficonfig_media_boot_option *opt,
756 efi_handle_t *volume_handles,
757 efi_status_t count)
758{
759 u32 i;
760 struct efi_handler *handler;
761 efi_status_t ret = EFI_SUCCESS;
762
763 for (i = 0; i < count; i++) {
764 u16 *p;
765 u16 dev_name[BOOTMENU_DEVICE_NAME_MAX];
766 char *optional_data;
767 struct efi_load_option lo;
768 char buf[BOOTMENU_DEVICE_NAME_MAX];
769 struct efi_device_path *device_path;
Raymond Mao7aa022c2023-06-19 14:23:01 -0700770 struct efi_device_path *short_dp;
Raymond Mao339b5272023-06-19 14:22:58 -0700771
772 ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler);
773 if (ret != EFI_SUCCESS)
774 continue;
775 ret = efi_protocol_open(handler, (void **)&device_path,
776 efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
777 if (ret != EFI_SUCCESS)
778 continue;
779
780 ret = efi_disk_get_device_name(volume_handles[i], buf, BOOTMENU_DEVICE_NAME_MAX);
781 if (ret != EFI_SUCCESS)
782 continue;
783
784 p = dev_name;
785 utf8_utf16_strncpy(&p, buf, strlen(buf));
786
Raymond Mao7aa022c2023-06-19 14:23:01 -0700787 /* prefer to short form device path */
788 short_dp = efi_dp_shorten(device_path);
789 if (short_dp)
790 device_path = short_dp;
791
Raymond Mao339b5272023-06-19 14:22:58 -0700792 lo.label = dev_name;
793 lo.attributes = LOAD_OPTION_ACTIVE;
794 lo.file_path = device_path;
795 lo.file_path_length = efi_dp_size(device_path) + sizeof(END);
796 /*
797 * Set the dedicated guid to optional_data, it is used to identify
798 * the boot option that automatically generated by the bootmenu.
799 * efi_serialize_load_option() expects optional_data is null-terminated
800 * utf8 string, so set the "1234567" string to allocate enough space
801 * to store guid, instead of realloc the load_option.
802 */
803 lo.optional_data = "1234567";
804 opt[i].size = efi_serialize_load_option(&lo, (u8 **)&opt[i].lo);
805 if (!opt[i].size) {
806 ret = EFI_OUT_OF_RESOURCES;
807 goto out;
808 }
809 /* set the guid */
810 optional_data = (char *)opt[i].lo + (opt[i].size - u16_strsize(u"1234567"));
811 memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t));
812 }
813
814out:
815 return ret;
816}
817
818/**
819 * efi_bootmgr_delete_invalid_boot_option() - delete non-existing boot option
820 *
821 * @opt: pointer to the media boot option structure
822 * @count: number of media boot option structure
823 * Return: status code
824 */
825static efi_status_t efi_bootmgr_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt,
826 efi_status_t count)
827{
828 efi_uintn_t size;
829 void *load_option;
830 u32 i, list_size = 0;
831 struct efi_load_option lo;
832 u16 *var_name16 = NULL;
833 u16 varname[] = u"Boot####";
834 efi_status_t ret = EFI_SUCCESS;
835 u16 *delete_index_list = NULL, *p;
836 efi_uintn_t buf_size;
837
838 buf_size = 128;
839 var_name16 = malloc(buf_size);
840 if (!var_name16)
841 return EFI_OUT_OF_RESOURCES;
842
843 var_name16[0] = 0;
844 for (;;) {
845 int index;
846 efi_guid_t guid;
847 efi_uintn_t tmp;
848
849 ret = efi_next_variable_name(&buf_size, &var_name16, &guid);
850 if (ret == EFI_NOT_FOUND) {
851 /*
852 * EFI_NOT_FOUND indicates we retrieved all EFI variables.
853 * This should be treated as success.
854 */
855 ret = EFI_SUCCESS;
856 break;
857 }
858
859 if (ret != EFI_SUCCESS)
860 goto out;
861
862 if (!efi_varname_is_load_option(var_name16, &index))
863 continue;
864
865 efi_create_indexed_name(varname, sizeof(varname), "Boot", index);
866 load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
867 if (!load_option)
868 continue;
869
870 tmp = size;
871 ret = efi_deserialize_load_option(&lo, load_option, &size);
872 if (ret != EFI_SUCCESS)
873 goto next;
874
875 if (size >= sizeof(efi_guid_bootmenu_auto_generated) &&
876 !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) {
877 for (i = 0; i < count; i++) {
878 if (opt[i].size == tmp &&
879 memcmp(opt[i].lo, load_option, tmp) == 0) {
880 opt[i].exist = true;
881 break;
882 }
883 }
884
885 /*
886 * The entire list of variables must be retrieved by
887 * efi_get_next_variable_name_int() before deleting the invalid
888 * boot option, just save the index here.
889 */
890 if (i == count) {
891 p = realloc(delete_index_list, sizeof(u32) *
892 (list_size + 1));
893 if (!p) {
894 ret = EFI_OUT_OF_RESOURCES;
895 goto out;
896 }
897 delete_index_list = p;
898 delete_index_list[list_size++] = index;
899 }
900 }
901next:
902 free(load_option);
903 }
904
905 /* delete all invalid boot options */
906 for (i = 0; i < list_size; i++) {
907 ret = efi_bootmgr_delete_boot_option(delete_index_list[i]);
908 if (ret != EFI_SUCCESS)
909 goto out;
910 }
911
912out:
913 free(var_name16);
914 free(delete_index_list);
915
916 return ret;
917}
918
919/**
920 * efi_bootmgr_get_unused_bootoption() - get unused "Boot####" index
921 *
922 * @buf: pointer to the buffer to store boot option variable name
923 * @buf_size: buffer size
924 * @index: pointer to store the index in the BootOrder variable
925 * Return: status code
926 */
927efi_status_t efi_bootmgr_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size,
928 unsigned int *index)
929{
930 u32 i;
931 efi_status_t ret;
932 efi_uintn_t size;
933
934 if (buf_size < u16_strsize(u"Boot####"))
935 return EFI_BUFFER_TOO_SMALL;
936
937 for (i = 0; i <= 0xFFFF; i++) {
938 size = 0;
939 efi_create_indexed_name(buf, buf_size, "Boot", i);
940 ret = efi_get_variable_int(buf, &efi_global_variable_guid,
941 NULL, &size, NULL, NULL);
942 if (ret == EFI_BUFFER_TOO_SMALL)
943 continue;
944 else
945 break;
946 }
947
948 if (i > 0xFFFF)
949 return EFI_OUT_OF_RESOURCES;
950
951 *index = i;
952
953 return EFI_SUCCESS;
954}
955
956/**
957 * efi_bootmgr_append_bootorder() - append new boot option in BootOrder variable
958 *
959 * @index: "Boot####" index to append to BootOrder variable
960 * Return: status code
961 */
962efi_status_t efi_bootmgr_append_bootorder(u16 index)
963{
964 u16 *bootorder;
965 efi_status_t ret;
966 u16 *new_bootorder = NULL;
967 efi_uintn_t last, size, new_size;
968
969 /* append new boot option */
970 bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
971 last = size / sizeof(u16);
972 new_size = size + sizeof(u16);
973 new_bootorder = calloc(1, new_size);
974 if (!new_bootorder) {
975 ret = EFI_OUT_OF_RESOURCES;
976 goto out;
977 }
978 memcpy(new_bootorder, bootorder, size);
979 new_bootorder[last] = index;
980
981 ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
982 EFI_VARIABLE_NON_VOLATILE |
983 EFI_VARIABLE_BOOTSERVICE_ACCESS |
984 EFI_VARIABLE_RUNTIME_ACCESS,
985 new_size, new_bootorder, false);
986 if (ret != EFI_SUCCESS)
987 goto out;
988
989out:
990 free(bootorder);
991 free(new_bootorder);
992
993 return ret;
994}
995
996/**
997 * efi_bootmgr_delete_boot_option() - delete selected boot option
998 *
999 * @boot_index: boot option index to delete
1000 * Return: status code
1001 */
1002efi_status_t efi_bootmgr_delete_boot_option(u16 boot_index)
1003{
1004 u16 *bootorder;
1005 u16 varname[9];
1006 efi_status_t ret;
1007 unsigned int index;
1008 efi_uintn_t num, size;
1009
1010 efi_create_indexed_name(varname, sizeof(varname),
1011 "Boot", boot_index);
1012 ret = efi_set_variable_int(varname, &efi_global_variable_guid,
1013 0, 0, NULL, false);
1014 if (ret != EFI_SUCCESS) {
1015 log_err("delete boot option(%ls) failed\n", varname);
1016 return ret;
1017 }
1018
1019 /* update BootOrder if necessary */
1020 bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
1021 if (!bootorder)
1022 return EFI_SUCCESS;
1023
1024 num = size / sizeof(u16);
1025 if (!efi_search_bootorder(bootorder, num, boot_index, &index))
1026 return EFI_SUCCESS;
1027
1028 memmove(&bootorder[index], &bootorder[index + 1],
1029 (num - index - 1) * sizeof(u16));
1030 size -= sizeof(u16);
1031 ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
1032 EFI_VARIABLE_NON_VOLATILE |
1033 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1034 EFI_VARIABLE_RUNTIME_ACCESS,
1035 size, bootorder, false);
1036
1037 return ret;
1038}
1039
1040/**
1041 * efi_bootmgr_update_media_device_boot_option() - generate the media device boot option
1042 *
1043 * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
1044 * and generate the bootmenu entries.
1045 * This function also provide the BOOT#### variable maintenance for
1046 * the media device entries.
1047 * - Automatically create the BOOT#### variable for the newly detected device,
1048 * this BOOT#### variable is distinguished by the special GUID
1049 * stored in the EFI_LOAD_OPTION.optional_data
1050 * - If the device is not attached to the system, the associated BOOT#### variable
1051 * is automatically deleted.
1052 *
1053 * Return: status code
1054 */
1055efi_status_t efi_bootmgr_update_media_device_boot_option(void)
1056{
1057 u32 i;
1058 efi_status_t ret;
1059 efi_uintn_t count;
1060 efi_handle_t *volume_handles = NULL;
1061 struct eficonfig_media_boot_option *opt = NULL;
1062
1063 ret = efi_locate_handle_buffer_int(BY_PROTOCOL,
1064 &efi_simple_file_system_protocol_guid,
1065 NULL, &count,
1066 (efi_handle_t **)&volume_handles);
1067 if (ret != EFI_SUCCESS)
Raymond Mao9945bc42023-06-19 14:22:59 -07001068 goto out;
Raymond Mao339b5272023-06-19 14:22:58 -07001069
1070 opt = calloc(count, sizeof(struct eficonfig_media_boot_option));
Raymond Mao9945bc42023-06-19 14:22:59 -07001071 if (!opt) {
1072 ret = EFI_OUT_OF_RESOURCES;
Raymond Mao339b5272023-06-19 14:22:58 -07001073 goto out;
Raymond Mao9945bc42023-06-19 14:22:59 -07001074 }
Raymond Mao339b5272023-06-19 14:22:58 -07001075
1076 /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */
1077 ret = efi_bootmgr_enumerate_boot_option(opt, volume_handles, count);
1078 if (ret != EFI_SUCCESS)
1079 goto out;
1080
1081 /*
1082 * System hardware configuration may vary depending on the user setup.
1083 * The boot option is automatically added by the bootmenu.
1084 * If the device is not attached to the system, the boot option needs
1085 * to be deleted.
1086 */
1087 ret = efi_bootmgr_delete_invalid_boot_option(opt, count);
1088 if (ret != EFI_SUCCESS)
1089 goto out;
1090
1091 /* add non-existent boot option */
1092 for (i = 0; i < count; i++) {
1093 u32 boot_index;
1094 u16 var_name[9];
1095
1096 if (!opt[i].exist) {
1097 ret = efi_bootmgr_get_unused_bootoption(var_name, sizeof(var_name),
1098 &boot_index);
1099 if (ret != EFI_SUCCESS)
1100 goto out;
1101
1102 ret = efi_set_variable_int(var_name, &efi_global_variable_guid,
1103 EFI_VARIABLE_NON_VOLATILE |
1104 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1105 EFI_VARIABLE_RUNTIME_ACCESS,
1106 opt[i].size, opt[i].lo, false);
1107 if (ret != EFI_SUCCESS)
1108 goto out;
1109
1110 ret = efi_bootmgr_append_bootorder(boot_index);
1111 if (ret != EFI_SUCCESS) {
1112 efi_set_variable_int(var_name, &efi_global_variable_guid,
1113 0, 0, NULL, false);
1114 goto out;
1115 }
1116 }
1117 }
1118
1119out:
1120 if (opt) {
1121 for (i = 0; i < count; i++)
1122 free(opt[i].lo);
1123 }
1124 free(opt);
1125 efi_free_pool(volume_handles);
1126
Raymond Mao9945bc42023-06-19 14:22:59 -07001127 if (ret == EFI_NOT_FOUND)
1128 return EFI_SUCCESS;
Raymond Mao339b5272023-06-19 14:22:58 -07001129 return ret;
1130}
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +09001131
1132static struct efi_device_path *bootefi_image_path;
1133static struct efi_device_path *bootefi_device_path;
1134static void *image_addr;
1135static size_t image_size;
1136
1137/**
1138 * efi_get_image_parameters() - return image parameters
1139 *
1140 * @img_addr: address of loaded image in memory
1141 * @img_size: size of loaded image
1142 */
1143void efi_get_image_parameters(void **img_addr, size_t *img_size)
1144{
1145 *img_addr = image_addr;
1146 *img_size = image_size;
1147}
1148
1149/**
1150 * efi_clear_bootdev() - clear boot device
1151 */
1152void efi_clear_bootdev(void)
1153{
1154 efi_free_pool(bootefi_device_path);
1155 efi_free_pool(bootefi_image_path);
1156 bootefi_device_path = NULL;
1157 bootefi_image_path = NULL;
1158 image_addr = NULL;
1159 image_size = 0;
1160}
1161
1162/**
1163 * efi_set_bootdev() - set boot device
1164 *
1165 * This function is called when a file is loaded, e.g. via the 'load' command.
1166 * We use the path to this file to inform the UEFI binary about the boot device.
1167 *
1168 * @dev: device, e.g. "MMC"
1169 * @devnr: number of the device, e.g. "1:2"
1170 * @path: path to file loaded
1171 * @buffer: buffer with file loaded
1172 * @buffer_size: size of file loaded
1173 */
1174void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
1175 void *buffer, size_t buffer_size)
1176{
1177 struct efi_device_path *device, *image;
1178 efi_status_t ret;
1179
1180 log_debug("dev=%s, devnr=%s, path=%s, buffer=%p, size=%zx\n", dev,
1181 devnr, path, buffer, buffer_size);
1182
1183 /* Forget overwritten image */
1184 if (buffer + buffer_size >= image_addr &&
1185 image_addr + image_size >= buffer)
1186 efi_clear_bootdev();
1187
1188 /* Remember only PE-COFF and FIT images */
1189 if (efi_check_pe(buffer, buffer_size, NULL) != EFI_SUCCESS) {
1190 if (IS_ENABLED(CONFIG_FIT) &&
1191 !fit_check_format(buffer, IMAGE_SIZE_INVAL)) {
1192 /*
1193 * FIT images of type EFI_OS are started via command
1194 * bootm. We should not use their boot device with the
1195 * bootefi command.
1196 */
1197 buffer = 0;
1198 buffer_size = 0;
1199 } else {
1200 log_debug("- not remembering image\n");
1201 return;
1202 }
1203 }
1204
1205 /* efi_set_bootdev() is typically called repeatedly, recover memory */
1206 efi_clear_bootdev();
1207
1208 image_addr = buffer;
1209 image_size = buffer_size;
1210
1211 ret = efi_dp_from_name(dev, devnr, path, &device, &image);
1212 if (ret == EFI_SUCCESS) {
1213 bootefi_device_path = device;
1214 if (image) {
1215 /* FIXME: image should not contain device */
1216 struct efi_device_path *image_tmp = image;
1217
1218 efi_dp_split_file_path(image, &device, &image);
1219 efi_free_pool(image_tmp);
1220 }
1221 bootefi_image_path = image;
1222 log_debug("- boot device %pD\n", device);
1223 if (image)
1224 log_debug("- image %pD\n", image);
1225 } else {
1226 log_debug("- efi_dp_from_name() failed, err=%lx\n", ret);
1227 efi_clear_bootdev();
1228 }
1229}
1230
1231/**
1232 * efi_env_set_load_options() - set load options from environment variable
1233 *
1234 * @handle: the image handle
1235 * @env_var: name of the environment variable
1236 * @load_options: pointer to load options (output)
1237 * Return: status code
1238 */
1239efi_status_t efi_env_set_load_options(efi_handle_t handle,
1240 const char *env_var,
1241 u16 **load_options)
1242{
1243 const char *env = env_get(env_var);
1244 size_t size;
1245 u16 *pos;
1246 efi_status_t ret;
1247
1248 *load_options = NULL;
1249 if (!env)
1250 return EFI_SUCCESS;
1251 size = sizeof(u16) * (utf8_utf16_strlen(env) + 1);
1252 pos = calloc(size, 1);
1253 if (!pos)
1254 return EFI_OUT_OF_RESOURCES;
1255 *load_options = pos;
1256 utf8_utf16_strcpy(&pos, env);
1257 ret = efi_set_load_options(handle, size, *load_options);
1258 if (ret != EFI_SUCCESS) {
1259 free(*load_options);
1260 *load_options = NULL;
1261 }
1262 return ret;
1263}
1264
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +09001265/**
1266 * copy_fdt() - Copy the device tree to a new location available to EFI
1267 *
1268 * The FDT is copied to a suitable location within the EFI memory map.
1269 * Additional 12 KiB are added to the space in case the device tree needs to be
1270 * expanded later with fdt_open_into().
1271 *
1272 * @fdtp: On entry a pointer to the flattened device tree.
1273 * On exit a pointer to the copy of the flattened device tree.
1274 * FDT start
1275 * Return: status code
1276 */
1277static efi_status_t copy_fdt(void **fdtp)
1278{
1279 unsigned long fdt_ram_start = -1L, fdt_pages;
1280 efi_status_t ret = 0;
1281 void *fdt, *new_fdt;
1282 u64 new_fdt_addr;
1283 uint fdt_size;
1284 int i;
1285
1286 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
1287 u64 ram_start = gd->bd->bi_dram[i].start;
1288 u64 ram_size = gd->bd->bi_dram[i].size;
1289
1290 if (!ram_size)
1291 continue;
1292
1293 if (ram_start < fdt_ram_start)
1294 fdt_ram_start = ram_start;
1295 }
1296
1297 /*
1298 * Give us at least 12 KiB of breathing room in case the device tree
1299 * needs to be expanded later.
1300 */
1301 fdt = *fdtp;
1302 fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + 0x3000);
1303 fdt_size = fdt_pages << EFI_PAGE_SHIFT;
1304
1305 ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
1306 EFI_ACPI_RECLAIM_MEMORY, fdt_pages,
1307 &new_fdt_addr);
1308 if (ret != EFI_SUCCESS) {
1309 log_err("ERROR: Failed to reserve space for FDT\n");
1310 goto done;
1311 }
1312 new_fdt = (void *)(uintptr_t)new_fdt_addr;
1313 memcpy(new_fdt, fdt, fdt_totalsize(fdt));
1314 fdt_set_totalsize(new_fdt, fdt_size);
1315
1316 *fdtp = (void *)(uintptr_t)new_fdt_addr;
1317done:
1318 return ret;
1319}
1320
1321/**
1322 * get_config_table() - get configuration table
1323 *
1324 * @guid: GUID of the configuration table
1325 * Return: pointer to configuration table or NULL
1326 */
1327static void *get_config_table(const efi_guid_t *guid)
1328{
1329 size_t i;
1330
1331 for (i = 0; i < systab.nr_tables; i++) {
1332 if (!guidcmp(guid, &systab.tables[i].guid))
1333 return systab.tables[i].table;
1334 }
1335 return NULL;
1336}
1337
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +09001338/**
1339 * efi_install_fdt() - install device tree
1340 *
1341 * If fdt is not EFI_FDT_USE_INTERNAL, the device tree located at that memory
1342 * address will be installed as configuration table, otherwise the device
1343 * tree located at the address indicated by environment variable fdt_addr or as
1344 * fallback fdtcontroladdr will be used.
1345 *
1346 * On architectures using ACPI tables device trees shall not be installed as
1347 * configuration table.
1348 *
1349 * @fdt: address of device tree or EFI_FDT_USE_INTERNAL to use
1350 * the hardware device tree as indicated by environment variable
1351 * fdt_addr or as fallback the internal device tree as indicated by
1352 * the environment variable fdtcontroladdr
1353 * Return: status code
1354 */
1355efi_status_t efi_install_fdt(void *fdt)
1356{
Tom Rini1373ffd2023-12-18 08:31:50 -05001357 struct bootm_headers img = { 0 };
1358 efi_status_t ret;
1359
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +09001360 /*
1361 * The EBBR spec requires that we have either an FDT or an ACPI table
1362 * but not both.
1363 */
Tom Rini1373ffd2023-12-18 08:31:50 -05001364 if (CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) && fdt)
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +09001365 log_warning("WARNING: Can't have ACPI table and device tree - ignoring DT.\n");
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +09001366
1367 if (fdt == EFI_FDT_USE_INTERNAL) {
1368 const char *fdt_opt;
1369 uintptr_t fdt_addr;
1370
1371 /* Look for device tree that is already installed */
1372 if (get_config_table(&efi_guid_fdt))
1373 return EFI_SUCCESS;
1374 /* Check if there is a hardware device tree */
1375 fdt_opt = env_get("fdt_addr");
1376 /* Use our own device tree as fallback */
1377 if (!fdt_opt) {
1378 fdt_opt = env_get("fdtcontroladdr");
1379 if (!fdt_opt) {
1380 log_err("ERROR: need device tree\n");
1381 return EFI_NOT_FOUND;
1382 }
1383 }
1384 fdt_addr = hextoul(fdt_opt, NULL);
1385 if (!fdt_addr) {
1386 log_err("ERROR: invalid $fdt_addr or $fdtcontroladdr\n");
1387 return EFI_LOAD_ERROR;
1388 }
1389 fdt = map_sysmem(fdt_addr, 0);
1390 }
1391
1392 /* Install device tree */
1393 if (fdt_check_header(fdt)) {
1394 log_err("ERROR: invalid device tree\n");
1395 return EFI_LOAD_ERROR;
1396 }
1397
Tom Rini1373ffd2023-12-18 08:31:50 -05001398 /* Create memory reservations as indicated by the device tree */
1399 efi_carve_out_dt_rsv(fdt);
1400
1401 if (CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE))
1402 return EFI_SUCCESS;
1403
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +09001404 /* Prepare device tree for payload */
1405 ret = copy_fdt(&fdt);
1406 if (ret) {
1407 log_err("ERROR: out of memory\n");
1408 return EFI_OUT_OF_RESOURCES;
1409 }
1410
1411 if (image_setup_libfdt(&img, fdt, NULL)) {
1412 log_err("ERROR: failed to process device tree\n");
1413 return EFI_LOAD_ERROR;
1414 }
1415
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +09001416 efi_try_purge_kaslr_seed(fdt);
1417
1418 if (CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL_MEASURE_DTB)) {
1419 ret = efi_tcg2_measure_dtb(fdt);
1420 if (ret == EFI_SECURITY_VIOLATION) {
1421 log_err("ERROR: failed to measure DTB\n");
1422 return ret;
1423 }
1424 }
1425
1426 /* Install device tree as UEFI table */
1427 ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
1428 if (ret != EFI_SUCCESS) {
1429 log_err("ERROR: failed to install device tree\n");
1430 return ret;
1431 }
AKASHI Takahiro0bef4b02023-11-21 10:29:44 +09001432
1433 return EFI_SUCCESS;
1434}
1435
1436/**
1437 * do_bootefi_exec() - execute EFI binary
1438 *
1439 * The image indicated by @handle is started. When it returns the allocated
1440 * memory for the @load_options is freed.
1441 *
1442 * @handle: handle of loaded image
1443 * @load_options: load options
1444 * Return: status code
1445 *
1446 * Load the EFI binary into a newly assigned memory unwinding the relocation
1447 * information, install the loaded image protocol, and call the binary.
1448 */
1449static efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options)
1450{
1451 efi_status_t ret;
1452 efi_uintn_t exit_data_size = 0;
1453 u16 *exit_data = NULL;
1454 struct efi_event *evt;
1455
1456 /* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */
1457 switch_to_non_secure_mode();
1458
1459 /*
1460 * The UEFI standard requires that the watchdog timer is set to five
1461 * minutes when invoking an EFI boot option.
1462 *
1463 * Unified Extensible Firmware Interface (UEFI), version 2.7 Errata A
1464 * 7.5. Miscellaneous Boot Services - EFI_BOOT_SERVICES.SetWatchdogTimer
1465 */
1466 ret = efi_set_watchdog(300);
1467 if (ret != EFI_SUCCESS) {
1468 log_err("ERROR: Failed to set watchdog timer\n");
1469 goto out;
1470 }
1471
1472 /* Call our payload! */
1473 ret = EFI_CALL(efi_start_image(handle, &exit_data_size, &exit_data));
1474 if (ret != EFI_SUCCESS) {
1475 log_err("## Application failed, r = %lu\n",
1476 ret & ~EFI_ERROR_MASK);
1477 if (exit_data) {
1478 log_err("## %ls\n", exit_data);
1479 efi_free_pool(exit_data);
1480 }
1481 }
1482
1483 efi_restore_gd();
1484
1485out:
1486 free(load_options);
1487
1488 if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) {
1489 if (efi_initrd_deregister() != EFI_SUCCESS)
1490 log_err("Failed to remove loadfile2 for initrd\n");
1491 }
1492
1493 /* Notify EFI_EVENT_GROUP_RETURN_TO_EFIBOOTMGR event group. */
1494 list_for_each_entry(evt, &efi_events, link) {
1495 if (evt->group &&
1496 !guidcmp(evt->group,
1497 &efi_guid_event_group_return_to_efibootmgr)) {
1498 efi_signal_event(evt);
1499 EFI_CALL(systab.boottime->close_event(evt));
1500 break;
1501 }
1502 }
1503
1504 /* Control is returned to U-Boot, disable EFI watchdog */
1505 efi_set_watchdog(0);
1506
1507 return ret;
1508}
1509
1510/**
1511 * efi_bootmgr_run() - execute EFI boot manager
1512 * @fdt: Flat device tree
1513 *
1514 * Invoke EFI boot manager and execute a binary depending on
1515 * boot options. If @fdt is not NULL, it will be passed to
1516 * the executed binary.
1517 *
1518 * Return: status code
1519 */
1520efi_status_t efi_bootmgr_run(void *fdt)
1521{
1522 efi_handle_t handle;
1523 void *load_options;
1524 efi_status_t ret;
1525
1526 /* Initialize EFI drivers */
1527 ret = efi_init_obj_list();
1528 if (ret != EFI_SUCCESS) {
1529 log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
1530 ret & ~EFI_ERROR_MASK);
1531 return CMD_RET_FAILURE;
1532 }
1533
1534 ret = efi_install_fdt(fdt);
1535 if (ret != EFI_SUCCESS)
1536 return ret;
1537
1538 ret = efi_bootmgr_load(&handle, &load_options);
1539 if (ret != EFI_SUCCESS) {
1540 log_notice("EFI boot manager: Cannot load any image\n");
1541 return ret;
1542 }
1543
1544 return do_bootefi_exec(handle, load_options);
1545}
1546
1547/**
1548 * efi_run_image() - run loaded UEFI image
1549 *
1550 * @source_buffer: memory address of the UEFI image
1551 * @source_size: size of the UEFI image
1552 * Return: status code
1553 */
1554efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size)
1555{
1556 efi_handle_t mem_handle = NULL, handle;
1557 struct efi_device_path *file_path = NULL;
1558 struct efi_device_path *msg_path;
1559 efi_status_t ret, ret2;
1560 u16 *load_options;
1561
1562 if (!bootefi_device_path || !bootefi_image_path) {
1563 log_debug("Not loaded from disk\n");
1564 /*
1565 * Special case for efi payload not loaded from disk,
1566 * such as 'bootefi hello' or for example payload
1567 * loaded directly into memory via JTAG, etc:
1568 */
1569 file_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
1570 (uintptr_t)source_buffer,
1571 source_size);
1572 /*
1573 * Make sure that device for device_path exist
1574 * in load_image(). Otherwise, shell and grub will fail.
1575 */
1576 ret = efi_install_multiple_protocol_interfaces(&mem_handle,
1577 &efi_guid_device_path,
1578 file_path, NULL);
1579 if (ret != EFI_SUCCESS)
1580 goto out;
1581 msg_path = file_path;
1582 } else {
1583 file_path = efi_dp_append(bootefi_device_path,
1584 bootefi_image_path);
1585 msg_path = bootefi_image_path;
1586 log_debug("Loaded from disk\n");
1587 }
1588
1589 log_info("Booting %pD\n", msg_path);
1590
1591 ret = EFI_CALL(efi_load_image(false, efi_root, file_path, source_buffer,
1592 source_size, &handle));
1593 if (ret != EFI_SUCCESS) {
1594 log_err("Loading image failed\n");
1595 goto out;
1596 }
1597
1598 /* Transfer environment variable as load options */
1599 ret = efi_env_set_load_options(handle, "bootargs", &load_options);
1600 if (ret != EFI_SUCCESS)
1601 goto out;
1602
1603 ret = do_bootefi_exec(handle, load_options);
1604
1605out:
1606 ret2 = efi_uninstall_multiple_protocol_interfaces(mem_handle,
1607 &efi_guid_device_path,
1608 file_path, NULL);
1609 efi_free_pool(file_path);
1610 return (ret != EFI_SUCCESS) ? ret : ret2;
1611}
1612
1613/**
1614 * efi_binary_run() - run loaded UEFI image
1615 *
1616 * @image: memory address of the UEFI image
1617 * @size: size of the UEFI image
1618 * @fdt: device-tree
1619 *
1620 * Execute an EFI binary image loaded at @image.
1621 * @size may be zero if the binary is loaded with U-Boot load command.
1622 *
1623 * Return: status code
1624 */
1625efi_status_t efi_binary_run(void *image, size_t size, void *fdt)
1626{
1627 efi_status_t ret;
1628
1629 /* Initialize EFI drivers */
1630 ret = efi_init_obj_list();
1631 if (ret != EFI_SUCCESS) {
1632 log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
1633 ret & ~EFI_ERROR_MASK);
1634 return -1;
1635 }
1636
1637 ret = efi_install_fdt(fdt);
1638 if (ret != EFI_SUCCESS)
1639 return ret;
1640
1641 return efi_run_image(image, size);
1642}