efi_loader: Pass in the required parameters from EFI bootmeth
Rather than setting up the global variables and then making the call,
pass them into function directly. This cleans up the code and makes it
all a bit easier to understand.
Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index a299845..b745ba8 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -52,40 +52,6 @@
device_get_uclass_id(media) == UCLASS_ETH;
}
-static void set_efi_bootdev(struct blk_desc *desc, struct bootflow *bflow)
-{
- const struct udevice *media_dev;
- int size = bflow->size;
- const char *dev_name;
- char devnum_str[9];
- char dirname[200];
- char *last_slash;
-
- /*
- * This is a horrible hack to tell EFI about this boot device. Once we
- * unify EFI with the rest of U-Boot we can clean this up. The same hack
- * exists in multiple places, e.g. in the fs, tftp and load commands.
- *
- * Once we can clean up the EFI code to make proper use of driver model,
- * this can go away.
- */
- media_dev = dev_get_parent(bflow->dev);
- snprintf(devnum_str, sizeof(devnum_str), "%x:%x",
- desc ? desc->devnum : dev_seq(media_dev),
- bflow->part);
-
- strlcpy(dirname, bflow->fname, sizeof(dirname));
- last_slash = strrchr(dirname, '/');
- if (last_slash)
- *last_slash = '\0';
-
- dev_name = device_get_uclass_id(media_dev) == UCLASS_MASS_STORAGE ?
- "usb" : blk_get_uclass_name(device_get_uclass_id(media_dev));
- log_debug("setting bootdev %s, %s, %s, %p, %x\n",
- dev_name, devnum_str, bflow->fname, bflow->buf, size);
- efi_set_bootdev(dev_name, devnum_str, bflow->fname, bflow->buf, size);
-}
-
static int efiload_read_file(struct bootflow *bflow, ulong addr)
{
struct blk_desc *desc = NULL;
@@ -102,8 +68,6 @@
return log_msg_ret("rdf", ret);
bflow->buf = map_sysmem(addr, bflow->size);
- set_efi_bootdev(desc, bflow);
-
return 0;
}
@@ -344,17 +308,8 @@
fdt = env_get_hex("fdt_addr_r", 0);
}
- if (bflow->flags & BOOTFLOWF_USE_BUILTIN_FDT) {
- log_debug("Booting with built-in fdt\n");
- if (efi_binary_run(map_sysmem(kernel, 0), bflow->size,
- EFI_FDT_USE_INTERNAL))
- return log_msg_ret("run", -EINVAL);
- } else {
- log_debug("Booting with external fdt\n");
- if (efi_binary_run(map_sysmem(kernel, 0), bflow->size,
- map_sysmem(fdt, 0)))
- return log_msg_ret("run", -EINVAL);
- }
+ if (efi_bootflow_run(bflow))
+ return log_msg_ret("run", -EINVAL);
return 0;
}
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 5bf271a..dcae6a7 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -20,6 +20,7 @@
#include <linux/oid_registry.h>
struct blk_desc;
+struct bootflow;
struct jmp_buf_data;
#if CONFIG_IS_ENABLED(EFI_LOADER)
@@ -590,6 +591,15 @@
efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options);
/* Run loaded UEFI image with given fdt */
efi_status_t efi_binary_run(void *image, size_t size, void *fdt);
+
+/**
+ * efi_bootflow_run() - Run a bootflow containing an EFI application
+ *
+ * @bootflow: Bootflow to run
+ * Return: Status code, something went wrong
+ */
+efi_status_t efi_bootflow_run(struct bootflow *bootflow);
+
/* Initialize variable services */
efi_status_t efi_init_variables(void);
/* Notify ExitBootServices() is called */
diff --git a/lib/efi_loader/efi_bootbin.c b/lib/efi_loader/efi_bootbin.c
index dce154e..fdde536 100644
--- a/lib/efi_loader/efi_bootbin.c
+++ b/lib/efi_loader/efi_bootbin.c
@@ -6,13 +6,16 @@
#define LOG_CATEGORY LOGC_EFI
+#include <bootflow.h>
#include <charset.h>
+#include <dm.h>
#include <efi.h>
#include <efi_loader.h>
#include <env.h>
#include <image.h>
#include <log.h>
#include <malloc.h>
+#include <mapmem.h>
static struct efi_device_path *bootefi_image_path;
static struct efi_device_path *bootefi_device_path;
@@ -284,3 +287,71 @@
return ret;
}
+
+/**
+ * calc_dev_name() - Calculate the device name to give to EFI
+ *
+ * If not supported, this shows an error.
+ *
+ * Return name, or NULL if not supported
+ */
+static const char *calc_dev_name(struct bootflow *bflow)
+{
+ const struct udevice *media_dev;
+
+ media_dev = dev_get_parent(bflow->dev);
+
+ if (!bflow->blk) {
+ log_err("Cannot boot EFI app on media '%s'\n",
+ dev_get_uclass_name(media_dev));
+
+ return NULL;
+ }
+
+ if (device_get_uclass_id(media_dev) == UCLASS_MASS_STORAGE)
+ return "usb";
+
+ return blk_get_uclass_name(device_get_uclass_id(media_dev));
+}
+
+efi_status_t efi_bootflow_run(struct bootflow *bflow)
+{
+ struct efi_device_path *device, *image;
+ const struct udevice *media_dev;
+ struct blk_desc *desc = NULL;
+ const char *dev_name;
+ char devnum_str[9];
+ efi_status_t ret;
+ void *fdt;
+
+ media_dev = dev_get_parent(bflow->dev);
+ if (bflow->blk) {
+ desc = dev_get_uclass_plat(bflow->blk);
+
+ snprintf(devnum_str, sizeof(devnum_str), "%x:%x",
+ desc ? desc->devnum : dev_seq(media_dev), bflow->part);
+ } else {
+ *devnum_str = '\0';
+ }
+
+ dev_name = calc_dev_name(bflow);
+ log_debug("dev_name '%s' devnum_str '%s' fname '%s' media_dev '%s'\n",
+ dev_name, devnum_str, bflow->fname, media_dev->name);
+ if (!dev_name)
+ return EFI_UNSUPPORTED;
+ ret = calculate_paths(dev_name, devnum_str, bflow->fname, &device,
+ &image);
+ if (ret)
+ return ret;
+
+ if (bflow->flags & BOOTFLOWF_USE_BUILTIN_FDT) {
+ log_debug("Booting with built-in fdt\n");
+ fdt = EFI_FDT_USE_INTERNAL;
+ } else {
+ log_debug("Booting with external fdt\n");
+ fdt = map_sysmem(bflow->fdt_addr, 0);
+ }
+ ret = efi_binary_run_dp(bflow->buf, bflow->size, fdt, device, image);
+
+ return ret;
+}