
From: Simon Glass <sjg@chromium.org> Move this function and some dependencies into the lib/efi directory so that it can be used by the app, which does not enable CONFIG_EFI_LOADER Since the networking has an #ifdef add CONFIG_EFI_LOADER to it, since the definitions are in efi_loader.h for now. Signed-off-by: Simon Glass <sjg@chromium.org> --- include/blk.h | 1 + include/efi.h | 36 +++++++++ lib/efi/Makefile | 1 + lib/efi/run.c | 139 ++++++++++++++++++++++++++++++++++ lib/efi_loader/efi_bootbin.c | 141 +---------------------------------- 5 files changed, 181 insertions(+), 137 deletions(-) create mode 100644 lib/efi/run.c diff --git a/include/blk.h b/include/blk.h index 84c19ca887d..64e9fc09433 100644 --- a/include/blk.h +++ b/include/blk.h @@ -7,6 +7,7 @@ #ifndef BLK_H #define BLK_H +#include <linux/types.h> #include <bouncebuf.h> #include <dm/uclass-id.h> #include <efi.h> diff --git a/include/efi.h b/include/efi.h index 2de732cec91..efdd980fbc3 100644 --- a/include/efi.h +++ b/include/efi.h @@ -737,4 +737,40 @@ static inline bool efi_use_host_arch(void) */ int efi_get_pxe_arch(void); +/** + * calculate_paths() - Calculate the device and image patch from strings + * + * @dev: device, e.g. "MMC" + * @devnr: number of the device, e.g. "1:2" + * @path: path to file loaded + * @device_pathp: returns EFI device path + * @image_pathp: returns EFI image path + * Return: EFI_SUCCESS on success, else error code + */ +efi_status_t calculate_paths(const char *dev, const char *devnr, + const char *path, + struct efi_device_path **device_pathp, + struct efi_device_path **image_pathp); + +/** + * efi_binary_run_dp() - run loaded UEFI image + * + * @image: memory address of the UEFI image + * @size: size of the UEFI image + * @fdt: device-tree + * @initrd: initrd + * @initrd_sz: initrd size + * @dp_dev: EFI device-path + * @dp_img: EFI image-path + * + * Execute an EFI binary image loaded at @image. + * @size may be zero if the binary is loaded with U-Boot load command. + * + * Return: status code + */ +efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt, + void *initrd, size_t initrd_sz, + struct efi_device_path *dp_dev, + struct efi_device_path *dp_img); + #endif /* _LINUX_EFI_H */ diff --git a/lib/efi/Makefile b/lib/efi/Makefile index 8d880319696..37816a93192 100644 --- a/lib/efi/Makefile +++ b/lib/efi/Makefile @@ -5,3 +5,4 @@ obj-y += basename.o obj-y += device_path.o +obj-y += run.o diff --git a/lib/efi/run.c b/lib/efi/run.c new file mode 100644 index 00000000000..93b32396805 --- /dev/null +++ b/lib/efi/run.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2016 Alexander Graf + * Copyright 2023 Google LLC + */ + +#define LOG_CATEGORY LOGC_EFI + +#include <blk.h> +#include <bootflow.h> +#include <dm.h> +#include <efi.h> +#include <efi_device_path.h> +#include <efi_loader.h> +#include <malloc.h> +#include <mapmem.h> +#include <net-common.h> + +/** + * calculate_paths() - Calculate the device and image patch from strings + * + * @dev: device, e.g. "MMC" + * @devnr: number of the device, e.g. "1:2" + * @path: path to file loaded + * @device_pathp: returns EFI device path + * @image_pathp: returns EFI image path + * Return: EFI_SUCCESS on success, else error code + */ +efi_status_t calculate_paths(const char *dev, const char *devnr, + const char *path, + struct efi_device_path **device_pathp, + struct efi_device_path **image_pathp) +{ + struct efi_device_path *image, *device; + efi_status_t ret; + +#if IS_ENABLED(CONFIG_NETDEVICES) && IS_ENABLED(CONFIG_EFI_LOADER) + if (!strcmp(dev, "Net") || !strcmp(dev, "Http")) { + ret = efi_net_new_dp(dev, devnr, eth_get_dev()); + if (ret != EFI_SUCCESS) + return ret; + } +#endif + + ret = efi_dp_from_name(dev, devnr, path, &device, &image); + if (ret != EFI_SUCCESS) + return ret; + + *device_pathp = device; + if (image) { + /* FIXME: image should not contain device */ + struct efi_device_path *image_tmp = image; + + efi_dp_split_file_path(image, &device, &image); + efi_free_pool(image_tmp); + } + *image_pathp = image; + log_debug("- boot device %pD\n", device); + if (image) + log_debug("- image %pD\n", image); + + return EFI_SUCCESS; +} + +/** + * 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) { + if (device_get_uclass_id(media_dev) == UCLASS_ETH) + return "Net"; + + 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 EFI_UNSUPPORTED; + + 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); + } + + if (IS_ENABLED(CONFIG_EFI_APP)) + return EFI_UNSUPPORTED; + + ret = efi_binary_run_dp(bflow->buf, bflow->size, fdt, NULL, 0, device, + image); + + return ret; +} diff --git a/lib/efi_loader/efi_bootbin.c b/lib/efi_loader/efi_bootbin.c index d232f450c66..81df1184834 100644 --- a/lib/efi_loader/efi_bootbin.c +++ b/lib/efi_loader/efi_bootbin.c @@ -49,52 +49,6 @@ void efi_clear_bootdev(void) image_size = 0; } -/** - * calculate_paths() - Calculate the device and image patch from strings - * - * @dev: device, e.g. "MMC" - * @devnr: number of the device, e.g. "1:2" - * @path: path to file loaded - * @device_pathp: returns EFI device path - * @image_pathp: returns EFI image path - * Return: EFI_SUCCESS on success, else error code - */ -static efi_status_t calculate_paths(const char *dev, const char *devnr, - const char *path, - struct efi_device_path **device_pathp, - struct efi_device_path **image_pathp) -{ - struct efi_device_path *image, *device; - efi_status_t ret; - -#if IS_ENABLED(CONFIG_NETDEVICES) - if (!strcmp(dev, "Net") || !strcmp(dev, "Http")) { - ret = efi_net_new_dp(dev, devnr, eth_get_dev()); - if (ret != EFI_SUCCESS) - return ret; - } -#endif - - ret = efi_dp_from_name(dev, devnr, path, &device, &image); - if (ret != EFI_SUCCESS) - return ret; - - *device_pathp = device; - if (image) { - /* FIXME: image should not contain device */ - struct efi_device_path *image_tmp = image; - - efi_dp_split_file_path(image, &device, &image); - efi_free_pool(image_tmp); - } - *image_pathp = image; - log_debug("- boot device %pD\n", device); - if (image) - log_debug("- image %pD\n", image); - - return EFI_SUCCESS; -} - /** * efi_set_bootdev() - set boot device * @@ -199,26 +153,10 @@ out: return ret; } -/** - * efi_binary_run_dp() - run loaded UEFI image - * - * @image: memory address of the UEFI image - * @size: size of the UEFI image - * @fdt: device-tree - * @initrd: initrd - * @initrd_sz: initrd size - * @dp_dev: EFI device-path - * @dp_img: EFI image-path - * - * Execute an EFI binary image loaded at @image. - * @size may be zero if the binary is loaded with U-Boot load command. - * - * Return: status code - */ -static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt, - void *initrd, size_t initrd_sz, - struct efi_device_path *dp_dev, - struct efi_device_path *dp_img) +efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt, + void *initrd, size_t initrd_sz, + struct efi_device_path *dp_dev, + struct efi_device_path *dp_img) { efi_status_t ret; @@ -301,74 +239,3 @@ out: 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) { - if (device_get_uclass_id(media_dev) == UCLASS_ETH) - return "Net"; - - 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 EFI_UNSUPPORTED; - - 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, NULL, 0, device, image); - - return ret; -} -- 2.43.0