Signed-off-by: AKASHI Takahiro <takahiro.aka...@linaro.org>
---
 cmd/bootefi.c                     | 61 ++++++++++++++-----------------
 include/efi_loader.h              |  4 +-
 lib/efi_loader/efi_image_loader.c | 61 +++++++++++++++++++------------
 3 files changed, 67 insertions(+), 59 deletions(-)
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index ebe149dffa1f..d2130d5ac323 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -249,12 +249,12 @@ static efi_status_t efi_install_fdt(ulong fdt_addr)
 static efi_status_t bootefi_run_prepare(const char *load_options_path,
                struct efi_device_path *device_path,
                struct efi_device_path *image_path,
-               struct efi_loaded_image_obj **image_objp,
+               efi_handle_t *handlep,
                struct efi_loaded_image **loaded_image_infop)
 {
        efi_status_t ret;
 
-       ret = efi_setup_loaded_image(device_path, image_path, image_objp,
+       ret = efi_setup_loaded_image(device_path, image_path, handlep,
                                     loaded_image_infop);
        if (ret != EFI_SUCCESS)
                return ret;
@@ -268,15 +268,15 @@ static efi_status_t bootefi_run_prepare(const char 
*load_options_path,
 /**
  * bootefi_run_finish() - finish up after running an EFI test
  *
+ * @handle: Handle to the loaded image object
  * @loaded_image_info: Pointer to a struct which holds the loaded image info
- * @image_objj: Pointer to a struct which holds the loaded image object
  */
-static void bootefi_run_finish(struct efi_loaded_image_obj *image_obj,
+static void bootefi_run_finish(efi_handle_t handle,
                               struct efi_loaded_image *loaded_image_info)
 {
        efi_restore_gd();
        free(loaded_image_info->load_options);
-       efi_delete_handle(&image_obj->header);
+       efi_delete_handle(handle);
 }
 
 static int efi_handle_fdt(char *fdt_opt)
@@ -319,10 +319,10 @@ static efi_status_t do_bootefi_exec(void *efi,
                                    struct efi_device_path *device_path,
                                    struct efi_device_path *image_path)
 {
-       efi_handle_t mem_handle = NULL;
        struct efi_device_path *memdp = NULL;
+       efi_handle_t handle;
        efi_status_t ret;
-       struct efi_loaded_image_obj *image_obj = NULL;
+       struct efi_loaded_image_obj *image_obj;
        struct efi_loaded_image *loaded_image_info = NULL;
 
        EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
@@ -342,28 +342,27 @@ static efi_status_t do_bootefi_exec(void *efi,
                 * Grub expects that the device path of the loaded image is
                 * installed on a handle.
                 */
-               ret = efi_create_handle(&mem_handle);
-               if (ret != EFI_SUCCESS)
-                       return ret; /* TODO: leaks device_path */
-               ret = efi_add_protocol(mem_handle, &efi_guid_device_path,
-                                      device_path);
-               if (ret != EFI_SUCCESS)
-                       goto err_add_protocol;
+               /*
+                * CHECK: device path protocol will be added to handle
+                * in efi_setup_loaded_image() anyway.
+                */
        } else {
                assert(device_path && image_path);
        }
 
        ret = bootefi_run_prepare("bootargs", device_path, image_path,
-                                 &image_obj, &loaded_image_info);
+                                 &handle, &loaded_image_info);
        if (ret)
                goto err_prepare;
 
        /* Load the EFI payload */
-       entry = efi_load_pe(image_obj, efi, loaded_image_info);
-       if (!entry) {
+       image_obj = handle->platdata;
+       ret = efi_load_pe(image_obj, efi, loaded_image_info);
+       if (ret) {
                ret = EFI_LOAD_ERROR;
                goto err_prepare;
        }
+       entry = image_obj->entry;
 
        if (memdp) {
                struct efi_device_path_memory *mdp = (void *)memdp;
@@ -393,7 +392,7 @@ static efi_status_t do_bootefi_exec(void *efi,
 
                /* Move into EL2 and keep running there */
                armv8_switch_to_el2((ulong)entry,
-                                   (ulong)&image_obj->header,
+                                   0,
                                    (ulong)&systab, 0, (ulong)efi_run_in_el2,
                                    ES_TO_AARCH64);
 
@@ -410,7 +409,7 @@ static efi_status_t do_bootefi_exec(void *efi,
                secure_ram_addr(_do_nonsec_entry)(
                                        efi_run_in_hyp,
                                        (uintptr_t)entry,
-                                       (uintptr_t)&image_obj->header,
+                                       0,
                                        (uintptr_t)&systab);
 
                /* Should never reach here, efi exits with longjmp */
@@ -418,15 +417,11 @@ static efi_status_t do_bootefi_exec(void *efi,
        }
 #endif
 
-       ret = efi_do_enter(&image_obj->header, &systab, entry);
+       ret = efi_do_enter(handle, &systab, entry);
 
 err_prepare:
        /* image has returned, loaded-image obj goes *poof*: */
-       bootefi_run_finish(image_obj, loaded_image_info);
-
-err_add_protocol:
-       if (mem_handle)
-               efi_delete_handle(mem_handle);
+       bootefi_run_finish(handle, loaded_image_info);
 
        return ret;
 }
@@ -438,9 +433,7 @@ err_add_protocol:
  * This sets things up so we can call EFI functions. This involves preparing
  * the 'gd' pointer and setting up the load ed image data structures.
  *
- * @image_objp: loaded_image_infop: Pointer to a struct which will hold the
- *    loaded image object. This struct will be inited by this function before
- *    use.
+ * @handlep: Pointer to a handle of the loaded image object
  * @loaded_image_infop: Pointer to a struct which will hold the loaded image
  *    info. This struct will be inited by this function before use.
  * @path: File path to the test being run (often just the test name with a
@@ -450,7 +443,7 @@ err_add_protocol:
  * @return 0 if OK, -ve on error
  */
 static efi_status_t bootefi_test_prepare
-               (struct efi_loaded_image_obj **image_objp,
+               (efi_handle_t *handlep,
                struct efi_loaded_image **loaded_image_infop, const char *path,
                ulong test_func, const char *load_options_path)
 {
@@ -465,7 +458,7 @@ static efi_status_t bootefi_test_prepare
                return EFI_OUT_OF_RESOURCES;
 
        return bootefi_run_prepare(load_options_path, bootefi_device_path,
-                                  bootefi_image_path, image_objp,
+                                  bootefi_image_path, handlep,
                                   loaded_image_infop);
 }
 
@@ -558,20 +551,20 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int 
argc, char * const argv[])
 #endif
 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
        if (!strcmp(argv[1], "selftest")) {
-               struct efi_loaded_image_obj *image_obj;
+               efi_handle_t handle;
                struct efi_loaded_image *loaded_image_info;
 
                if (efi_handle_fdt(argc > 2 ? argv[2] : NULL))
                        return CMD_RET_FAILURE;
 
-               if (bootefi_test_prepare(&image_obj, &loaded_image_info,
+               if (bootefi_test_prepare(&handle, &loaded_image_info,
                                         "\\selftest", (uintptr_t)&efi_selftest,
                                         "efi_selftest"))
                        return CMD_RET_FAILURE;
 
                /* Execute the test */
-               r = efi_selftest(&image_obj->header, &systab);
-               bootefi_run_finish(image_obj, loaded_image_info);
+               r = efi_selftest(handle, &systab);
+               bootefi_run_finish(handle, loaded_image_info);
                return r != EFI_SUCCESS;
        } else
 #endif
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 5882cd7dd3b0..86cf91a6feca 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -274,8 +274,8 @@ efi_status_t efi_set_watchdog(unsigned long timeout);
 /* Called from places to check whether a timer expired */
 void efi_timer_check(void);
 /* PE loader implementation */
-void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
-                 struct efi_loaded_image *loaded_image_info);
+efi_status_t efi_load_pe(struct efi_loaded_image_obj *obj, void *efi,
+                        struct efi_loaded_image *loaded_image_info);
 /* Called once to store the pristine gd pointer */
 void efi_save_gd(void);
 /* Special case handler for error/abort that just tries to dtrt to get
diff --git a/lib/efi_loader/efi_image_loader.c 
b/lib/efi_loader/efi_image_loader.c
index a18ce0a5705e..332dd5db199c 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <efi_loader.h>
 #include <pe.h>
 
@@ -66,6 +67,7 @@ static efi_status_t efi_print_image_info(struct 
efi_loaded_image_obj *obj,
        if (image->file_path)
                printf(" '%pD'", image->file_path);
        printf("\n");
+
        return EFI_SUCCESS;
 }
 
@@ -76,17 +78,27 @@ static efi_status_t efi_print_image_info(struct 
efi_loaded_image_obj *obj,
  */
 void efi_print_image_infos(void *pc)
 {
-       struct efi_object *efiobj;
+       struct uclass *uc;
+       struct udevice *dev, *protocol;
+       struct efi_loaded_image_obj *obj;
        struct efi_handler *handler;
+       efi_status_t ret;
 
-       list_for_each_entry(efiobj, &efi_obj_list, link) {
-               list_for_each_entry(handler, &efiobj->protocols, link) {
-                       if (!guidcmp(handler->guid, &efi_guid_loaded_image)) {
-                               efi_print_image_info(
-                                       (struct efi_loaded_image_obj *)efiobj,
-                                       handler->protocol_interface, pc);
-                       }
-               }
+       if (uclass_get(UCLASS_EFI_OBJECT, &uc))
+               return;
+
+       uclass_foreach_dev(dev, uc) {
+               if (strcmp(dev->driver->name, "efi_loaded_image"))
+                       continue;
+
+               ret = efi_search_protocol(dev, &efi_guid_loaded_image,
+                                         &protocol);
+               if (ret != EFI_SUCCESS)
+                       continue;
+
+               obj = dev->platdata;
+               handler = protocol->uclass_platdata;
+               efi_print_image_info(obj, handler->protocol_interface, pc);
        }
 }
 
@@ -198,8 +210,8 @@ static void efi_set_code_and_data_type(
  * piece of memory. On successful load it then returns the entry point for
  * the binary. Otherwise NULL.
  */
-void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
-                 struct efi_loaded_image *loaded_image_info)
+efi_status_t efi_load_pe(struct efi_loaded_image_obj *obj, void *efi,
+                        struct efi_loaded_image *loaded_image_info)
 {
        IMAGE_NT_HEADERS32 *nt;
        IMAGE_DOS_HEADER *dos;
@@ -215,17 +227,18 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, 
void *efi,
        uint64_t image_size;
        unsigned long virt_size = 0;
        int supported = 0;
+       efi_status_t ret;
 
        dos = efi;
        if (dos->e_magic != IMAGE_DOS_SIGNATURE) {
                printf("%s: Invalid DOS Signature\n", __func__);
-               return NULL;
+               return EFI_INVALID_PARAMETER;
        }
 
        nt = (void *) ((char *)efi + dos->e_lfanew);
        if (nt->Signature != IMAGE_NT_SIGNATURE) {
                printf("%s: Invalid NT Signature\n", __func__);
-               return NULL;
+               return EFI_INVALID_PARAMETER;
        }
 
        for (i = 0; machines[i]; i++)
@@ -237,7 +250,7 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void 
*efi,
        if (!supported) {
                printf("%s: Machine type 0x%04x is not supported\n",
                       __func__, nt->FileHeader.Machine);
-               return NULL;
+               return EFI_UNSUPPORTED;
        }
 
        /* Calculate upper virtual address boundary */
@@ -263,7 +276,7 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void 
*efi,
                if (!efi_reloc) {
                        printf("%s: Could not allocate %lu bytes\n",
                               __func__, virt_size);
-                       return NULL;
+                       return EFI_OUT_OF_RESOURCES;
                }
                entry = efi_reloc + opt->AddressOfEntryPoint;
                rel_size = opt->DataDirectory[rel_idx].Size;
@@ -279,7 +292,7 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void 
*efi,
                if (!efi_reloc) {
                        printf("%s: Could not allocate %lu bytes\n",
                               __func__, virt_size);
-                       return NULL;
+                       return EFI_OUT_OF_RESOURCES;
                }
                entry = efi_reloc + opt->AddressOfEntryPoint;
                rel_size = opt->DataDirectory[rel_idx].Size;
@@ -288,7 +301,7 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void 
*efi,
        } else {
                printf("%s: Invalid optional header magic %x\n", __func__,
                       nt->OptionalHeader.Magic);
-               return NULL;
+               return EFI_INVALID_PARAMETER;
        }
 
        /* Load sections into RAM */
@@ -302,11 +315,12 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, 
void *efi,
        }
 
        /* Run through relocations */
-       if (efi_loader_relocate(rel, rel_size, efi_reloc,
-                               (unsigned long)image_base) != EFI_SUCCESS) {
+       ret = efi_loader_relocate(rel, rel_size, efi_reloc,
+                                 (unsigned long)image_base);
+       if (ret != EFI_SUCCESS) {
                efi_free_pages((uintptr_t) efi_reloc,
                               (virt_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT);
-               return NULL;
+               return ret;
        }
 
        /* Flush cache */
@@ -317,8 +331,9 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void 
*efi,
        /* Populate the loaded image interface bits */
        loaded_image_info->image_base = efi;
        loaded_image_info->image_size = image_size;
-       handle->reloc_base = efi_reloc;
-       handle->reloc_size = virt_size;
+       obj->reloc_base = efi_reloc;
+       obj->reloc_size = virt_size;
+       obj->entry = entry;
 
-       return entry;
+       return EFI_SUCCESS;
 }
-- 
2.19.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to