From patchwork Fri Feb 8 08:15:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1038511 X-Patchwork-Delegate: agraf@suse.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="eyTHb1X4"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43wp2B5dqrz9sML for ; Fri, 8 Feb 2019 19:17:22 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 5D81FC21F3B; Fri, 8 Feb 2019 08:17:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_IN_DNSWL_BLOCKED, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 553BBC21F90; Fri, 8 Feb 2019 08:15:18 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id A2513C21F5B; Fri, 8 Feb 2019 08:15:10 +0000 (UTC) Received: from mail-yb1-f195.google.com (mail-yb1-f195.google.com [209.85.219.195]) by lists.denx.de (Postfix) with ESMTPS id E835EC2201E for ; Fri, 8 Feb 2019 08:15:04 +0000 (UTC) Received: by mail-yb1-f195.google.com with SMTP id s17so1093763ybp.6 for ; Fri, 08 Feb 2019 00:15:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=udkWHCHWk5u+Lg8FoSfMmLEKmp1sAQsXmyIPytZLcWE=; b=eyTHb1X4MNwfO+FYl+nFJ20LjEiI9WL1cD/LH0AUc89VGDPzg3R7zd+bWI67d2AHrJ ivP+OWLf6gA6j6Jm0XP98A+yoQvx4nFN8nawSRvZ2/bce9q8AVVvjuDik+jFDjq7iicX wueSDUaox8CEcUABUhi81Qqos+7IZlddjrLbW5oFr9TMzdLBWs+fPp/bihTtw7/n0iqs 7nxbIy6g+0szPaNeiR4t2lxkQEdmMY6B/mhyZ2yrNxNSjnF6mn07r7p7Hn0MIriFoIzG Qk4YX9aSA0L9lUcDFPYOPvHQwtyhgMaSF9mS1Hx/I0fVKEwhRYMMEzctmfrb91ZITZ7Z Y7BQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=udkWHCHWk5u+Lg8FoSfMmLEKmp1sAQsXmyIPytZLcWE=; b=DttC2b0wpUwVD/8Xzg5XxqMskn1Ws4ZqWxvjaFcnqHxAKSa6i31kxmddnAiucnLwh1 nE+YV2GBrI+CeNn3EvGfK9K9RJl2q7z+ajWIeZEmduFfmNa8DeIgqFk2qxtW03k0jQ+t G+T6wYQ+acEg9PqP8uIXEIei+yodkp8bTJ2kluAyzmeen/9qJH78nOqx9BZ+grcQH9rB zwn7LNEE+xkcryN1NKvDzi3qrzVAorEcj3O2UJFL3vG+64u5K2ybawdzv3XfjexTS0TR ifJvi62l4OlP5MIQ0DWA83sdbPVhCFHm8iQu7TffyahfolFA8YF1YW+oIKdDVSH8E/kA Y5Ug== X-Gm-Message-State: AHQUAuayWxx4dB0Vy/yuOucHcrVd2kcmnemHyllRQ3vk42XDwXM4mg/R 73qkS7wyfcJB7/qYKgs+pvd6jA== X-Google-Smtp-Source: AHgI3IYBwvterajQftjExce/3uKATrJgVwwPFna02k/zSsAcju8cJZMTmTRf9Fix7Jm8PMJxpiq3Xw== X-Received: by 2002:a25:1ed7:: with SMTP id e206mr16317410ybe.508.1549613703589; Fri, 08 Feb 2019 00:15:03 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id j6sm561090ywi.110.2019.02.08.00.15.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 08 Feb 2019 00:15:03 -0800 (PST) From: AKASHI Takahiro To: trini@konsulko.com, agraf@suse.de, xypron.glpk@gmx.de, sjg@chromium.org Date: Fri, 8 Feb 2019 17:15:30 +0900 Message-Id: <20190208081542.2813-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190208081542.2813-1-takahiro.akashi@linaro.org> References: <20190208081542.2813-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [RFC v2 03/15] efi_loader: image_loader: aligned with DM X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Signed-off-by: AKASHI Takahiro --- 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 +#include #include #include @@ -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; }