On 10/10/2017 02:23 PM, Rob Clark wrote:
When we don't have a real device/image path, such as 'bootefi hello',
construct a mem-mapped device-path.

This fixes 'bootefi hello' after devicepath refactoring.

Fixes: 95c5553ea2 ("efi_loader: refactor boot device and loaded_image handling")
Signed-off-by: Rob Clark <robdcl...@gmail.com>
---
  cmd/bootefi.c                            | 23 +++++++++++++++++++++++
  include/efi_api.h                        |  8 ++++++++
  include/efi_loader.h                     |  3 +++
  lib/efi_loader/efi_device_path.c         | 24 ++++++++++++++++++++++++
  lib/efi_loader/efi_device_path_to_text.c |  9 +++++++++
  5 files changed, 67 insertions(+)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 24958ada46..18176a1266 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -128,6 +128,7 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt,
  {
        struct efi_loaded_image loaded_image_info = {};
        struct efi_object loaded_image_info_obj = {};
+       struct efi_device_path *memdp = NULL;
        ulong ret;
ulong (*entry)(void *image_handle, struct efi_system_table *st)
@@ -136,6 +137,20 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt,
        const efi_guid_t fdt_guid = EFI_FDT_GUID;
        bootm_headers_t img = { 0 };
+ /*
+        * Special case for efi payload not loaded from disk, such as
+        * 'bootefi hello' or for example payload loaded directly into
+        * memory via jtag/etc:
+        */
+       if (!device_path && !image_path) {
+               printf("WARNING: using memory device/image path, this may confuse 
some payloads!\n");
+               /* actual addresses filled in after efi_load_pe() */
+               memdp = efi_dp_from_mem(0, 0, 0);
+               device_path = image_path = memdp;
+       } else {
+               assert(device_path && image_path);
+       }
+
        /* Initialize and populate EFI object list */
        if (!efi_obj_list_initalized)
                efi_init_obj_list();
@@ -182,6 +197,14 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt,
                goto exit;
        }
+ if (memdp) {
+               struct efi_device_path_memory *mdp = (void *)memdp;
+               mdp->memory_type = loaded_image_info.image_code_type;
+               mdp->start_address = (uintptr_t)loaded_image_info.image_base;
+               mdp->end_address = mdp->start_address +
+                               loaded_image_info.image_size;
+       }
+
        /* we don't support much: */
        
env_set("efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported",
                "{ro,boot}(blob)0000000000000000");
diff --git a/include/efi_api.h b/include/efi_api.h
index 9610d03d47..07b2af7020 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -299,8 +299,16 @@ struct efi_mac_addr {
  } __packed;
#define DEVICE_PATH_TYPE_HARDWARE_DEVICE 0x01
+#  define DEVICE_PATH_SUB_TYPE_MEMORY          0x03
  #  define DEVICE_PATH_SUB_TYPE_VENDOR         0x04
+struct efi_device_path_memory {
+       struct efi_device_path dp;
+       u32 memory_type;
+       u64 start_address;
+       u64 end_address;
+} __packed;
+
  struct efi_device_path_vendor {
        struct efi_device_path dp;
        efi_guid_t guid;
diff --git a/include/efi_loader.h b/include/efi_loader.h
index fa4e1cdb1c..db805e898f 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -269,6 +269,9 @@ struct efi_device_path *efi_dp_from_part(struct blk_desc 
*desc, int part);
  struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
                                         const char *path);
  struct efi_device_path *efi_dp_from_eth(void);
+struct efi_device_path *efi_dp_from_mem(uint32_t mem_type,
+                                       uint64_t start_address,
+                                       uint64_t end_address);
  void efi_dp_split_file_path(struct efi_device_path *full_path,
                            struct efi_device_path **device_path,
                            struct efi_device_path **file_path);
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 5d5c3b3464..f6e368e029 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -538,6 +538,30 @@ struct efi_device_path *efi_dp_from_eth(void)
  }
  #endif
+/* Construct a device-path for memory-mapped image */
+struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
+                                       uint64_t start_address,
+                                       uint64_t end_address)
+{
+       struct efi_device_path_memory *mdp;
+       void *buf, *start;
+
+       start = buf = dp_alloc(sizeof(*mdp) + sizeof(END));
+
+       mdp = buf;
+       mdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
+       mdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MEMORY;
+       mdp->dp.length = sizeof(*mdp);
+       mdp->memory_type = memory_type;
+       mdp->start_address = start_address;
+       mdp->end_address = end_address;
+       buf = &mdp[1];
+
+       *((struct efi_device_path *)buf) = END;
+
+       return start;
+}
+
  /*
   * Helper to split a full device path (containing both device and file
   * parts) into it's constituent parts.
diff --git a/lib/efi_loader/efi_device_path_to_text.c 
b/lib/efi_loader/efi_device_path_to_text.c
index 1a5ef3919b..62771338f0 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -24,6 +24,15 @@ static char *dp_unknown(char *s, struct efi_device_path *dp)
  static char *dp_hardware(char *s, struct efi_device_path *dp)
  {
        switch (dp->sub_type) {
+       case DEVICE_PATH_SUB_TYPE_MEMORY: {
+               struct efi_device_path_memory *mdp =
+                       (struct efi_device_path_memory *)dp;
+               s += sprintf(s, "/MemoryMapped(0x%x,0x%llx,0x%llx)",
+                            mdp->memory_type,
+                            mdp->start_address,
+                            mdp->end_address);
+               break;
+       }
        case DEVICE_PATH_SUB_TYPE_VENDOR: {
                struct efi_device_path_vendor *vdp =
                        (struct efi_device_path_vendor *)dp;


Providing a dummmy device path for bootefi hello and bootefi selftest is reasonable.

Acked-by: Heinrich Schuchardt <xypron.g...@gmx.de>
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to