
From: Simon Glass <sjg@chromium.org> If the bootflow relates to the EFI bootmeth, show the device path along with the other info. Signed-off-by: Simon Glass <sjg@chromium.org> --- cmd/bootflow.c | 17 +++++++++++++++++ include/efi.h | 15 +++++++++++++++ include/efi_device_path.h | 14 ++++++++++++++ lib/efi/device_path.c | 37 +++++++++++++++++++++++++++++++++++++ lib/efi_client/app_run.c | 18 ++++++++++++++++++ 5 files changed, 101 insertions(+) diff --git a/cmd/bootflow.c b/cmd/bootflow.c index 464c3e40475..ae692cf521b 100644 --- a/cmd/bootflow.c +++ b/cmd/bootflow.c @@ -13,6 +13,7 @@ #include <command.h> #include <console.h> #include <dm.h> +#include <efi_device_path.h> #include <expo.h> #include <log.h> #include <mapmem.h> @@ -453,6 +454,22 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc, printf("FDT addr: %lx\n", bflow->fdt_addr); } printf("Error: %d\n", bflow->err); + if (IS_ENABLED(CONFIG_BOOTMETH_EFI) && + bflow->method->driver == DM_DRIVER_GET(bootmeth_4efi)) { + struct efi_device_path *dp; + bool alloced; + + ret = efi_dp_from_bootflow(bflow, &dp, &alloced); + printf("EFI path "); + if (!ret) { + printf("%pD\n", dp); + if (alloced) + efi_free_pool(dp); + } else { + printf("(err %dE)\n", ret); + } + } + if (dump && bflow->buf) { /* Set some sort of maximum on the size */ int size = min(bflow->size, 10 << 10); diff --git a/include/efi.h b/include/efi.h index 3558c03db23..c07717811da 100644 --- a/include/efi.h +++ b/include/efi.h @@ -23,6 +23,8 @@ #include <net.h> #endif +struct udevice; + /* Type INTN in UEFI specification */ #define efi_intn_t ssize_t /* Type UINTN in UEFI specification*/ @@ -848,4 +850,17 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size, struct efi_device_path *dp_dev, struct efi_device_path *dp_img); +/** + * efi_dp_from_bootdev() - Get the device path from a bootdev + * + * This is only available in the app. It looks up the bootdev and returns the + * assocated device path (attached to its sibling block device) + * + * @dev: UCLASS_BOOTDEV device to check + * @dpp: Returns device path on success + * Returns: 0 if OK, -ve on error + */ +int efi_dp_from_bootdev(const struct udevice *dev, + const struct efi_device_path **dpp); + #endif /* _LINUX_EFI_H */ diff --git a/include/efi_device_path.h b/include/efi_device_path.h index 2e425a6d82b..d030674d6bd 100644 --- a/include/efi_device_path.h +++ b/include/efi_device_path.h @@ -12,6 +12,7 @@ enum uclass_id; struct blk_desc; +struct bootflow; struct efi_load_option; struct udevice; @@ -429,4 +430,17 @@ struct efi_device_path *efi_dp_from_http(const char *server, const char *efi_dp_guess_uclass(struct efi_device_path *device_path, enum uclass_id *guessp); +/** + * efi_dp_from_bootflow() - Get the device path for a bootflow + * + * @bflow: Bootflow to check + * @dpp: Returns the device path + * @allocedp: if NULL, no allocation is permitted, otherwise retrusn true if + * efi_free_pool() must be called to free the device path + * Return: 0 if OK, -EINVAL if @allocedp is NULL and allocation is needed, + * -ve on error + */ +int efi_dp_from_bootflow(const struct bootflow *bflow, + struct efi_device_path **dpp, bool *allocedp); + #endif /* EFI_DEVICE_PATH_H */ diff --git a/lib/efi/device_path.c b/lib/efi/device_path.c index 191d58bbd2d..bae9e5c537a 100644 --- a/lib/efi/device_path.c +++ b/lib/efi/device_path.c @@ -8,6 +8,7 @@ #define LOG_CATEGORY LOGC_EFI #include <blk.h> +#include <bootflow.h> #include <dm.h> #include <dm/root.h> #include <efi_device_path.h> @@ -1376,3 +1377,39 @@ const char *efi_dp_guess_uclass(struct efi_device_path *device_path, return best_name; } +int efi_dp_from_bootflow(const struct bootflow *bflow, + struct efi_device_path **dpp, bool *allocedp) +{ + struct udevice *bdev = bflow->dev; + struct blk_desc *desc; + struct udevice *blk; + int ret; + + if (IS_ENABLED(CONFIG_EFI_APP)) { + const struct efi_device_path *dpc; + + ret = efi_dp_from_bootdev(bflow->dev, &dpc); + if (ret) + return log_msg_ret("dfa", ret); + *dpp = (struct efi_device_path *)dpc; + if (allocedp) + *allocedp = false; + } else { + struct efi_device_path *dp; + + if (!allocedp) + return log_msg_ret("dfb", -EINVAL); + ret = bootdev_get_sibling_blk(bdev, &blk); + if (ret) + return log_msg_ret("dfc", ret); + + desc = dev_get_uclass_plat(blk); + dp = efi_dp_from_part(desc, bflow->part); + if (!dp) + return log_msg_ret("dfd", -ENOMEM); + *allocedp = true; + *dpp = dp; + } + + return 0; +} diff --git a/lib/efi_client/app_run.c b/lib/efi_client/app_run.c index 03cc29778d8..9fc753ceed8 100644 --- a/lib/efi_client/app_run.c +++ b/lib/efi_client/app_run.c @@ -7,6 +7,7 @@ */ #include <bootm.h> +#include <dm.h> #include <efi.h> #include <efi_api.h> #include <efi_device_path.h> @@ -89,3 +90,20 @@ efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt, { return efi_run_image(image, size, dp_dev, dp_img); } + +int efi_dp_from_bootdev(const struct udevice *dev, + const struct efi_device_path **dpp) +{ + const struct udevice *media = dev_get_parent(dev); + const struct efi_media_plat *plat; + + log_debug("dev '%s': uclass ID %d\n", media->name, + device_get_uclass_id(media)); + if (device_get_uclass_id(media) != UCLASS_EFI_MEDIA) + return log_msg_ret("efb", -ENOTSUPP); + + plat = dev_get_plat(media); + *dpp = plat->device_path; + + return 0; +} -- 2.43.0