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