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