Merge tag 'tpm-master-28012025' of https://source.denx.de/u-boot/custodians/u-boot-tpm
[u-boot.git] / boot / bootmeth_efi_mgr.c
blob42b8863815e7dfcf06602eaeaa017dfd2d0b3886
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Bootmethod for EFI boot manager
5 * Copyright 2021 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
7 */
9 #define LOG_CATEGORY UCLASS_BOOTSTD
11 #include <bootdev.h>
12 #include <bootflow.h>
13 #include <bootmeth.h>
14 #include <command.h>
15 #include <dm.h>
16 #include <efi_loader.h>
17 #include <efi_variable.h>
18 #include <malloc.h>
20 /**
21 * struct efi_mgr_priv - private info for the efi-mgr driver
23 * @fake_bootflow: Fake a valid bootflow for testing
25 struct efi_mgr_priv {
26 bool fake_dev;
29 void sandbox_set_fake_efi_mgr_dev(struct udevice *dev, bool fake_dev)
31 struct efi_mgr_priv *priv = dev_get_priv(dev);
33 priv->fake_dev = fake_dev;
36 static int efi_mgr_check(struct udevice *dev, struct bootflow_iter *iter)
38 int ret;
40 /* Must be an bootstd device */
41 ret = bootflow_iter_check_system(iter);
42 if (ret)
43 return log_msg_ret("net", ret);
45 return 0;
48 static int efi_mgr_read_bootflow(struct udevice *dev, struct bootflow *bflow)
50 struct efi_mgr_priv *priv = dev_get_priv(dev);
51 efi_status_t ret;
52 efi_uintn_t size;
53 u16 *bootorder;
55 if (priv->fake_dev) {
56 bflow->state = BOOTFLOWST_READY;
57 return 0;
60 ret = efi_init_obj_list();
61 if (ret)
62 return log_msg_ret("init", ret);
64 /* Enable this method if the "BootOrder" UEFI exists. */
65 bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid,
66 &size);
67 if (bootorder) {
68 free(bootorder);
69 bflow->state = BOOTFLOWST_READY;
70 return 0;
73 return -EINVAL;
76 static int efi_mgr_read_file(struct udevice *dev, struct bootflow *bflow,
77 const char *file_path, ulong addr,
78 enum bootflow_img_t type, ulong *sizep)
80 /* Files are loaded by the 'bootefi bootmgr' command */
82 return -ENOSYS;
85 static int efi_mgr_boot(struct udevice *dev, struct bootflow *bflow)
87 int ret;
89 /* Booting is handled by the 'bootefi bootmgr' command */
90 ret = efi_bootmgr_run(EFI_FDT_USE_INTERNAL);
92 return 0;
95 static int bootmeth_efi_mgr_bind(struct udevice *dev)
97 struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
99 plat->desc = "EFI bootmgr flow";
100 plat->flags = BOOTMETHF_GLOBAL;
102 return 0;
105 static struct bootmeth_ops efi_mgr_bootmeth_ops = {
106 .check = efi_mgr_check,
107 .read_bootflow = efi_mgr_read_bootflow,
108 .read_file = efi_mgr_read_file,
109 .boot = efi_mgr_boot,
112 static const struct udevice_id efi_mgr_bootmeth_ids[] = {
113 { .compatible = "u-boot,efi-bootmgr" },
117 U_BOOT_DRIVER(bootmeth_3efi_mgr) = {
118 .name = "bootmeth_efi_mgr",
119 .id = UCLASS_BOOTMETH,
120 .of_match = efi_mgr_bootmeth_ids,
121 .ops = &efi_mgr_bootmeth_ops,
122 .bind = bootmeth_efi_mgr_bind,
123 .priv_auto = sizeof(struct efi_mgr_priv),