@@ -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);
@@ -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 */
@@ -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 */
@@ -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;
+}
@@ -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;
+}