[U-Boot] [RFC 6/8] cmd: bootefi: carve out efi_selftest code from do_bootefi()

AKASHI Takahiro
2019-03-05T05:53:35Z

This is a preparatory patch for reworking do_bootefi() in a later patch.

Efi_selftest code is unusual in terms of execution path in do_bootefi(),
which make that function complicated and hard to understand. With this
patch, all efi_selftest related code will be put in a separate function.

The change also includes expanding efi_run_prepare() and efi_run_finish()
in do_bootefi_exec().

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
cmd/bootefi.c | 146 +++++++++++++++++++++++++++++++-------------------
1 file changed, 91 insertions(+), 55 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 8915cdbfd5f5..1470122af266 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -232,39 +232,6 @@ static int efi_process_fdt(const char *fdt_opt)
return CMD_RET_SUCCESS;
}

-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,
- struct efi_loaded_image **loaded_image_infop)
-{
- efi_status_t ret;
-
- ret = efi_setup_loaded_image(device_path, image_path, image_objp,
- loaded_image_infop);
- if (ret != EFI_SUCCESS)
- return ret;
-
- /* Transfer environment variable as load options */
- set_load_options(*loaded_image_infop, load_options_path);
-
- return 0;
-}
-
-/**
- * bootefi_run_finish() - finish up after running an EFI test
- *
- * @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,
- struct efi_loaded_image *loaded_image_info)
-{
- efi_restore_gd();
- free(loaded_image_info->load_options);
- efi_delete_handle(&image_obj->header);
-}
-
/**
* do_bootefi_exec() - execute EFI binary
*
@@ -311,11 +278,14 @@ static efi_status_t do_bootefi_exec(void *efi,
assert(device_path && image_path);
}

- ret = bootefi_run_prepare("bootargs", device_path, image_path,
- &image_obj, &loaded_image_info);
+ ret = efi_setup_loaded_image(device_path, image_path, &image_obj,
+ &loaded_image_info);
if (ret)
goto err_prepare;

+ /* Transfer environment variable as load options */
+ set_load_options(loaded_image_info, "bootargs");
+
/* Load the EFI payload */
ret = efi_load_pe(image_obj, efi, loaded_image_info);
if (ret != EFI_SUCCESS)
@@ -339,7 +309,9 @@ static efi_status_t do_bootefi_exec(void *efi,

err_prepare:
/* image has returned, loaded-image obj goes *poof*: */
- bootefi_run_finish(image_obj, loaded_image_info);
+ efi_restore_gd();
+ free(loaded_image_info->load_options);
+ efi_delete_handle(&image_obj->header);

err_add_protocol:
if (mem_handle)
@@ -370,6 +342,25 @@ static int do_bootefi_bootmgr_exec(void)
}

#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
+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,
+ struct efi_loaded_image **loaded_image_infop)
+{
+ efi_status_t ret;
+
+ ret = efi_setup_loaded_image(device_path, image_path, image_objp,
+ loaded_image_infop);
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ /* Transfer environment variable as load options */
+ set_load_options(*loaded_image_infop, load_options_path);
+
+ return 0;
+}
+
/**
* bootefi_test_prepare() - prepare to run an EFI test
*
@@ -415,6 +406,63 @@ failure:
return ret;
}

+/**
+ * bootefi_run_finish() - finish up after running an EFI test
+ *
+ * @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,
+ struct efi_loaded_image *loaded_image_info)
+{
+ efi_restore_gd();
+ free(loaded_image_info->load_options);
+ efi_delete_handle(&image_obj->header);
+}
+
+/**
+ * do_efi_selftest() - execute EFI Selftest
+ *
+ * @fdt_opt: string of fdt start address
+ * Return: status code
+ *
+ * Execute EFI Selftest
+ */
+static int do_efi_selftest(const char *fdt_opt)
+{
+ struct efi_loaded_image_obj *image_obj;
+ struct efi_loaded_image *loaded_image_info;
+ efi_status_t r;
+ int ret;
+
+ /* Allow unaligned memory access */
+ allow_unaligned();
+
+ switch_to_non_secure_mode();
+
+ /* Initialize EFI drivers */
+ r = efi_init_obj_list();
+ if (r != EFI_SUCCESS) {
+ printf("Error: Cannot set up EFI drivers, r = %lu\n",
+ r & ~EFI_ERROR_MASK);
+ return CMD_RET_FAILURE;
+ }
+
+ ret = efi_process_fdt(fdt_opt);
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ r = bootefi_test_prepare(&image_obj, &loaded_image_info,
+ "\\selftest", "efi_selftest");
+ if (r != EFI_SUCCESS)
+ return CMD_RET_FAILURE;
+
+ /* Execute the test */
+ r = EFI_CALL(efi_selftest(&image_obj->header, &systab));
+ bootefi_run_finish(image_obj, loaded_image_info);
+
+ return r != EFI_SUCCESS;
+}
#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */

/* Interpreter command to boot an arbitrary EFI image from memory */
@@ -425,6 +473,13 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
efi_status_t r;
unsigned long fdt_addr;

+ if (argc < 2)
+ return CMD_RET_USAGE;
+#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
+ else if (!strcmp(argv[1], "selftest"))
+ return do_efi_selftest(argc > 2 ? argv[2] : NULL);
+#endif
+
/* Allow unaligned memory access */
allow_unaligned();

@@ -438,9 +493,6 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return CMD_RET_FAILURE;
}

- if (argc < 2)
- return CMD_RET_USAGE;
-
ret = fdt_process_fdt(argc > 2 ? argv[2] : NULL);
if (ret != EFI_SUCCESS)
return ret;
@@ -456,22 +508,6 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
addr = CONFIG_SYS_LOAD_ADDR;
memcpy(map_sysmem(addr, size), __efi_helloworld_begin, size);
} else
-#endif
-#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
- if (!strcmp(argv[1], "selftest")) {
- struct efi_loaded_image_obj *image_obj;
- struct efi_loaded_image *loaded_image_info;
-
- r = bootefi_test_prepare(&image_obj, &loaded_image_info,
- "\\selftest", "efi_selftest");
- if (r != EFI_SUCCESS)
- return CMD_RET_FAILURE;
-
- /* Execute the test */
- r = EFI_CALL(efi_selftest(&image_obj->header, &systab));
- bootefi_run_finish(image_obj, loaded_image_info);
- return r != EFI_SUCCESS;
- } else
#endif
if (!strcmp(argv[1], "bootmgr")) {
return do_bootefi_bootmgr_exec();
--
2.20.1