Re: [U-Boot] [RFC v3 09/10] efi_loader: rework bootmgr/bootefi using load_image API

2019-04-18 Thread Alexander Graf

On 16.04.19 18:20, Heinrich Schuchardt wrote:
> On 4/16/19 12:56 PM, Heinrich Schuchardt wrote:
>> On 4/16/19 6:24 AM, AKASHI Takahiro wrote:
>>> In the current implementation, bootefi command and EFI boot manager
>>> don't use load_image API, instead, use more primitive and internal
>>> functions. This will introduce duplicated code and potentially
>>> unknown bugs as well as inconsistent behaviours.
>>>
>>> With this patch, do_efibootmgr() and do_boot_efi() are completely
>>> overhauled and re-implemented using load_image API.
>>>
>>> Signed-off-by: AKASHI Takahiro 
>>> ---
>>>   cmd/bootefi.c | 197
>>> +++---
>>>   include/efi_loader.h  |   5 +-
>>>   lib/efi_loader/efi_bootmgr.c  |  43 
>>>   lib/efi_loader/efi_boottime.c |   2 +
>>>   4 files changed, 134 insertions(+), 113 deletions(-)
>>>
>>> diff --git a/cmd/bootefi.c b/cmd/bootefi.c
>>> index f14966961b23..97d49a53a44b 100644
>>> --- a/cmd/bootefi.c
>>> +++ b/cmd/bootefi.c
>>> @@ -222,88 +222,39 @@ static efi_status_t efi_install_fdt(const char
>>> *fdt_opt)
>>>   /**
>>>    * do_bootefi_exec() - execute EFI binary
>>>    *
>>> - * @efi:    address of the binary
>>> - * @device_path:    path of the device from which the binary was
>>> loaded
>>> - * @image_path:    device path of the binary
>>> + * @handle:    handle of loaded image
>>>    * Return:    status code
>>>    *
>>>    * Load the EFI binary into a newly assigned memory unwinding the
>>> relocation
>>>    * information, install the loaded image protocol, and call the
>>> binary.
>>>    */
>>> -static efi_status_t do_bootefi_exec(void *efi,
>>> -    struct efi_device_path *device_path,
>>> -    struct efi_device_path *image_path)
>>> +static efi_status_t do_bootefi_exec(efi_handle_t handle)
>>>   {
>>> -    efi_handle_t mem_handle = NULL;
>>> -    struct efi_device_path *memdp = NULL;
>>> -    efi_status_t ret;
>>> -    struct efi_loaded_image_obj *image_obj = NULL;
>>>   struct efi_loaded_image *loaded_image_info = NULL;
>>> -
>>> -    /*
>>> - * 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(EFI_RESERVED_MEMORY_TYPE, 0, 0);
>>> -    device_path = image_path = memdp;
>>> -    /*
>>> - * 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;
>>> -    } else {
>>> -    assert(device_path && image_path);
>>> -    }
>>> -
>>> -    ret = efi_setup_loaded_image(device_path, image_path, &image_obj,
>>> - &loaded_image_info);
>>> -    if (ret)
>>> -    goto err_prepare;
>>> +    efi_status_t ret;
>>>
>>>   /* Transfer environment variable as load options */
>>> -    set_load_options(loaded_image_info, "bootargs");
>>
>> In set_load_options() an error could occur (out of memory). So I think
>> it should return a status.
>>
>>> -
>>> -    /* Load the EFI payload */
>>> -    ret = efi_load_pe(image_obj, efi, loaded_image_info);
>>> +    ret = EFI_CALL(systab.boottime->open_protocol(
>>> +    handle,
>>> +    &efi_guid_loaded_image,
>>> +    (void **)&loaded_image_info,
>>> +    NULL, NULL,
>>> +    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
>>
>> Shouldn't we move this to set_load_options()?
>>
>>>   if (ret != EFI_SUCCESS)
>>> -    goto err_prepare;
>>> -
>>> -    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;
>>> -    }
>>> +    goto err;
>>> +    set_load_options(loaded_image_info, "bootargs");
>>>
>>>   /* we don't support much: */
>>>  
>>> env_set("efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported",
>>>
>>>   "{ro,boot}(blob)");
>>
>> Shouldn't this move to efi_setup.c? Probably we should also set
>> OsIndications. I would prefer using efi_set_variable(). I think moving
>> this could be done in a preparatory patch.
>>
>>>
>>>   /* Call our payload! */
>>> -  

Re: [U-Boot] [RFC v3 09/10] efi_loader: rework bootmgr/bootefi using load_image API

2019-04-17 Thread AKASHI Takahiro
Correction:

On Thu, Apr 18, 2019 at 09:13:52AM +0900, AKASHI Takahiro wrote:
> On Tue, Apr 16, 2019 at 12:56:32PM +0200, Heinrich Schuchardt wrote:
> > On 4/16/19 6:24 AM, AKASHI Takahiro wrote:
> > >In the current implementation, bootefi command and EFI boot manager
> > >don't use load_image API, instead, use more primitive and internal
> > >functions. This will introduce duplicated code and potentially
> > >unknown bugs as well as inconsistent behaviours.
> > >
> > >With this patch, do_efibootmgr() and do_boot_efi() are completely
> > >overhauled and re-implemented using load_image API.
> > >
> > >Signed-off-by: AKASHI Takahiro 
> > >---
> > >  cmd/bootefi.c | 197 +++---
> > >  include/efi_loader.h  |   5 +-
> > >  lib/efi_loader/efi_bootmgr.c  |  43 
> > >  lib/efi_loader/efi_boottime.c |   2 +
> > >  4 files changed, 134 insertions(+), 113 deletions(-)
> > >
> > >diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> > >index f14966961b23..97d49a53a44b 100644
> > >--- a/cmd/bootefi.c
> > >+++ b/cmd/bootefi.c
> > >@@ -222,88 +222,39 @@ static efi_status_t efi_install_fdt(const char 
> > >*fdt_opt)
> > >  /**
> > >   * do_bootefi_exec() - execute EFI binary
> > >   *
> > >- * @efi:  address of the binary
> > >- * @device_path:  path of the device from which the binary was loaded
> > >- * @image_path:   device path of the binary
> > >+ * @handle:   handle of loaded image
> > >   * Return:   status code
> > >   *
> > >   * Load the EFI binary into a newly assigned memory unwinding the 
> > > relocation
> > >   * information, install the loaded image protocol, and call the binary.
> > >   */
> > >-static efi_status_t do_bootefi_exec(void *efi,
> > >-  struct efi_device_path *device_path,
> > >-  struct efi_device_path *image_path)
> > >+static efi_status_t do_bootefi_exec(efi_handle_t handle)
> > >  {
> > >-  efi_handle_t mem_handle = NULL;
> > >-  struct efi_device_path *memdp = NULL;
> > >-  efi_status_t ret;
> > >-  struct efi_loaded_image_obj *image_obj = NULL;
> > >   struct efi_loaded_image *loaded_image_info = NULL;
> > >-
> > >-  /*
> > >-   * 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(EFI_RESERVED_MEMORY_TYPE, 0, 0);
> > >-  device_path = image_path = memdp;
> > >-  /*
> > >-   * 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;
> > >-  } else {
> > >-  assert(device_path && image_path);
> > >-  }
> > >-
> > >-  ret = efi_setup_loaded_image(device_path, image_path, &image_obj,
> > >-   &loaded_image_info);
> > >-  if (ret)
> > >-  goto err_prepare;
> > >+  efi_status_t ret;
> > >
> > >   /* Transfer environment variable as load options */
> > >-  set_load_options(loaded_image_info, "bootargs");
> > 
> > In set_load_options() an error could occur (out of memory). So I think
> > it should return a status.
> 
> I didn't change anything in set_load_options(), but I will follow
> your comment.
> 
> > >-
> > >-  /* Load the EFI payload */
> > >-  ret = efi_load_pe(image_obj, efi, loaded_image_info);
> > >+  ret = EFI_CALL(systab.boottime->open_protocol(
> > >+  handle,
> > >+  &efi_guid_loaded_image,
> > >+  (void **)&loaded_image_info,
> > >+  NULL, NULL,
> > >+  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
> > 
> > Shouldn't we move this to set_load_options()?
> 
> No. This line has nothing to do with "load options."

Wrong, I will follow your comment.
This change, however, uncovers one issue: Who is responsible
for freeing loaded_image_info->load_option, particularly,
when efi_exit()/unload_image() is fully implemented?
In such a case, we have no chance to access this handle,
hence loaded_image_info, after returning from efi_start_image().

Thanks,
-Takahiro Akashi

> > >   if (ret != EFI_SUCCESS)
> > >-  goto err_prepare;
> > >-
> > >-  if (memdp) {
> > >-  struct efi_device_path_memory *mdp = (void *)m

Re: [U-Boot] [RFC v3 09/10] efi_loader: rework bootmgr/bootefi using load_image API

2019-04-17 Thread AKASHI Takahiro
On Tue, Apr 16, 2019 at 12:56:32PM +0200, Heinrich Schuchardt wrote:
> On 4/16/19 6:24 AM, AKASHI Takahiro wrote:
> >In the current implementation, bootefi command and EFI boot manager
> >don't use load_image API, instead, use more primitive and internal
> >functions. This will introduce duplicated code and potentially
> >unknown bugs as well as inconsistent behaviours.
> >
> >With this patch, do_efibootmgr() and do_boot_efi() are completely
> >overhauled and re-implemented using load_image API.
> >
> >Signed-off-by: AKASHI Takahiro 
> >---
> >  cmd/bootefi.c | 197 +++---
> >  include/efi_loader.h  |   5 +-
> >  lib/efi_loader/efi_bootmgr.c  |  43 
> >  lib/efi_loader/efi_boottime.c |   2 +
> >  4 files changed, 134 insertions(+), 113 deletions(-)
> >
> >diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> >index f14966961b23..97d49a53a44b 100644
> >--- a/cmd/bootefi.c
> >+++ b/cmd/bootefi.c
> >@@ -222,88 +222,39 @@ static efi_status_t efi_install_fdt(const char 
> >*fdt_opt)
> >  /**
> >   * do_bootefi_exec() - execute EFI binary
> >   *
> >- * @efi:address of the binary
> >- * @device_path:path of the device from which the binary was loaded
> >- * @image_path: device path of the binary
> >+ * @handle: handle of loaded image
> >   * Return: status code
> >   *
> >   * Load the EFI binary into a newly assigned memory unwinding the 
> > relocation
> >   * information, install the loaded image protocol, and call the binary.
> >   */
> >-static efi_status_t do_bootefi_exec(void *efi,
> >-struct efi_device_path *device_path,
> >-struct efi_device_path *image_path)
> >+static efi_status_t do_bootefi_exec(efi_handle_t handle)
> >  {
> >-efi_handle_t mem_handle = NULL;
> >-struct efi_device_path *memdp = NULL;
> >-efi_status_t ret;
> >-struct efi_loaded_image_obj *image_obj = NULL;
> > struct efi_loaded_image *loaded_image_info = NULL;
> >-
> >-/*
> >- * 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(EFI_RESERVED_MEMORY_TYPE, 0, 0);
> >-device_path = image_path = memdp;
> >-/*
> >- * 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;
> >-} else {
> >-assert(device_path && image_path);
> >-}
> >-
> >-ret = efi_setup_loaded_image(device_path, image_path, &image_obj,
> >- &loaded_image_info);
> >-if (ret)
> >-goto err_prepare;
> >+efi_status_t ret;
> >
> > /* Transfer environment variable as load options */
> >-set_load_options(loaded_image_info, "bootargs");
> 
> In set_load_options() an error could occur (out of memory). So I think
> it should return a status.

I didn't change anything in set_load_options(), but I will follow
your comment.

> >-
> >-/* Load the EFI payload */
> >-ret = efi_load_pe(image_obj, efi, loaded_image_info);
> >+ret = EFI_CALL(systab.boottime->open_protocol(
> >+handle,
> >+&efi_guid_loaded_image,
> >+(void **)&loaded_image_info,
> >+NULL, NULL,
> >+EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
> 
> Shouldn't we move this to set_load_options()?

No. This line has nothing to do with "load options."

> > if (ret != EFI_SUCCESS)
> >-goto err_prepare;
> >-
> >-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;
> >-}
> >+goto err;
> >+set_load_options(loaded_image_info, "bootargs");
> >
> > /* we don't support much: */
> > 
> > env_set("efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported",
> > "{ro,boot}(blob)");
> 
> 

Re: [U-Boot] [RFC v3 09/10] efi_loader: rework bootmgr/bootefi using load_image API

2019-04-16 Thread Heinrich Schuchardt

On 4/16/19 12:56 PM, Heinrich Schuchardt wrote:

On 4/16/19 6:24 AM, AKASHI Takahiro wrote:

In the current implementation, bootefi command and EFI boot manager
don't use load_image API, instead, use more primitive and internal
functions. This will introduce duplicated code and potentially
unknown bugs as well as inconsistent behaviours.

With this patch, do_efibootmgr() and do_boot_efi() are completely
overhauled and re-implemented using load_image API.

Signed-off-by: AKASHI Takahiro 
---
  cmd/bootefi.c | 197 +++---
  include/efi_loader.h  |   5 +-
  lib/efi_loader/efi_bootmgr.c  |  43 
  lib/efi_loader/efi_boottime.c |   2 +
  4 files changed, 134 insertions(+), 113 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index f14966961b23..97d49a53a44b 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -222,88 +222,39 @@ static efi_status_t efi_install_fdt(const char 
*fdt_opt)

  /**
   * do_bootefi_exec() - execute EFI binary
   *
- * @efi:    address of the binary
- * @device_path:    path of the device from which the binary was loaded
- * @image_path:    device path of the binary
+ * @handle:    handle of loaded image
   * Return:    status code
   *
   * Load the EFI binary into a newly assigned memory unwinding the 
relocation

   * information, install the loaded image protocol, and call the binary.
   */
-static efi_status_t do_bootefi_exec(void *efi,
-    struct efi_device_path *device_path,
-    struct efi_device_path *image_path)
+static efi_status_t do_bootefi_exec(efi_handle_t handle)
  {
-    efi_handle_t mem_handle = NULL;
-    struct efi_device_path *memdp = NULL;
-    efi_status_t ret;
-    struct efi_loaded_image_obj *image_obj = NULL;
  struct efi_loaded_image *loaded_image_info = NULL;
-
-    /*
- * 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(EFI_RESERVED_MEMORY_TYPE, 0, 0);
-    device_path = image_path = memdp;
-    /*
- * 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;
-    } else {
-    assert(device_path && image_path);
-    }
-
-    ret = efi_setup_loaded_image(device_path, image_path, &image_obj,
- &loaded_image_info);
-    if (ret)
-    goto err_prepare;
+    efi_status_t ret;

  /* Transfer environment variable as load options */
-    set_load_options(loaded_image_info, "bootargs");


In set_load_options() an error could occur (out of memory). So I think
it should return a status.


-
-    /* Load the EFI payload */
-    ret = efi_load_pe(image_obj, efi, loaded_image_info);
+    ret = EFI_CALL(systab.boottime->open_protocol(
+    handle,
+    &efi_guid_loaded_image,
+    (void **)&loaded_image_info,
+    NULL, NULL,
+    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));


Shouldn't we move this to set_load_options()?


  if (ret != EFI_SUCCESS)
-    goto err_prepare;
-
-    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;
-    }
+    goto err;
+    set_load_options(loaded_image_info, "bootargs");

  /* we don't support much: */
  
env_set("efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported", 


  "{ro,boot}(blob)");


Shouldn't this move to efi_setup.c? Probably we should also set
OsIndications. I would prefer using efi_set_variable(). I think moving
this could be done in a preparatory patch.



  /* Call our payload! */
-    debug("%s: Jumping to 0x%p\n", __func__, image_obj->entry);
-    ret = EFI_CALL(efi_start_image(&image_obj->header, NULL, NULL));
+    ret = EFI_CALL(efi_start_image(handle, NULL, NULL));

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

+err:
  return ret;
  }

@@ -317,8 +268,7 @

Re: [U-Boot] [RFC v3 09/10] efi_loader: rework bootmgr/bootefi using load_image API

2019-04-16 Thread Heinrich Schuchardt

On 4/16/19 6:24 AM, AKASHI Takahiro wrote:

In the current implementation, bootefi command and EFI boot manager
don't use load_image API, instead, use more primitive and internal
functions. This will introduce duplicated code and potentially
unknown bugs as well as inconsistent behaviours.

With this patch, do_efibootmgr() and do_boot_efi() are completely
overhauled and re-implemented using load_image API.

Signed-off-by: AKASHI Takahiro 
---
  cmd/bootefi.c | 197 +++---
  include/efi_loader.h  |   5 +-
  lib/efi_loader/efi_bootmgr.c  |  43 
  lib/efi_loader/efi_boottime.c |   2 +
  4 files changed, 134 insertions(+), 113 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index f14966961b23..97d49a53a44b 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -222,88 +222,39 @@ static efi_status_t efi_install_fdt(const char *fdt_opt)
  /**
   * do_bootefi_exec() - execute EFI binary
   *
- * @efi:   address of the binary
- * @device_path:   path of the device from which the binary was loaded
- * @image_path:device path of the binary
+ * @handle:handle of loaded image
   * Return:status code
   *
   * Load the EFI binary into a newly assigned memory unwinding the relocation
   * information, install the loaded image protocol, and call the binary.
   */
-static efi_status_t do_bootefi_exec(void *efi,
-   struct efi_device_path *device_path,
-   struct efi_device_path *image_path)
+static efi_status_t do_bootefi_exec(efi_handle_t handle)
  {
-   efi_handle_t mem_handle = NULL;
-   struct efi_device_path *memdp = NULL;
-   efi_status_t ret;
-   struct efi_loaded_image_obj *image_obj = NULL;
struct efi_loaded_image *loaded_image_info = NULL;
-
-   /*
-* 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(EFI_RESERVED_MEMORY_TYPE, 0, 0);
-   device_path = image_path = memdp;
-   /*
-* 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;
-   } else {
-   assert(device_path && image_path);
-   }
-
-   ret = efi_setup_loaded_image(device_path, image_path, &image_obj,
-&loaded_image_info);
-   if (ret)
-   goto err_prepare;
+   efi_status_t ret;

/* Transfer environment variable as load options */
-   set_load_options(loaded_image_info, "bootargs");


In set_load_options() an error could occur (out of memory). So I think
it should return a status.


-
-   /* Load the EFI payload */
-   ret = efi_load_pe(image_obj, efi, loaded_image_info);
+   ret = EFI_CALL(systab.boottime->open_protocol(
+   handle,
+   &efi_guid_loaded_image,
+   (void **)&loaded_image_info,
+   NULL, NULL,
+   EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));


Shouldn't we move this to set_load_options()?


if (ret != EFI_SUCCESS)
-   goto err_prepare;
-
-   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;
-   }
+   goto err;
+   set_load_options(loaded_image_info, "bootargs");

/* we don't support much: */

env_set("efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported",
"{ro,boot}(blob)");


Shouldn't this move to efi_setup.c? Probably we should also set
OsIndications. I would prefer using efi_set_variable(). I think moving
this could be done in a preparatory patch.



/* Call our payload! */
-   debug("%s: Jumping to 0x%p\n", __func__, image_obj->entry);
-   ret = EFI_CALL(efi_start_image(&image_obj->header, 

[U-Boot] [RFC v3 09/10] efi_loader: rework bootmgr/bootefi using load_image API

2019-04-15 Thread AKASHI Takahiro
In the current implementation, bootefi command and EFI boot manager
don't use load_image API, instead, use more primitive and internal
functions. This will introduce duplicated code and potentially
unknown bugs as well as inconsistent behaviours.

With this patch, do_efibootmgr() and do_boot_efi() are completely
overhauled and re-implemented using load_image API.

Signed-off-by: AKASHI Takahiro 
---
 cmd/bootefi.c | 197 +++---
 include/efi_loader.h  |   5 +-
 lib/efi_loader/efi_bootmgr.c  |  43 
 lib/efi_loader/efi_boottime.c |   2 +
 4 files changed, 134 insertions(+), 113 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index f14966961b23..97d49a53a44b 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -222,88 +222,39 @@ static efi_status_t efi_install_fdt(const char *fdt_opt)
 /**
  * do_bootefi_exec() - execute EFI binary
  *
- * @efi:   address of the binary
- * @device_path:   path of the device from which the binary was loaded
- * @image_path:device path of the binary
+ * @handle:handle of loaded image
  * Return: status code
  *
  * Load the EFI binary into a newly assigned memory unwinding the relocation
  * information, install the loaded image protocol, and call the binary.
  */
-static efi_status_t do_bootefi_exec(void *efi,
-   struct efi_device_path *device_path,
-   struct efi_device_path *image_path)
+static efi_status_t do_bootefi_exec(efi_handle_t handle)
 {
-   efi_handle_t mem_handle = NULL;
-   struct efi_device_path *memdp = NULL;
-   efi_status_t ret;
-   struct efi_loaded_image_obj *image_obj = NULL;
struct efi_loaded_image *loaded_image_info = NULL;
-
-   /*
-* 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(EFI_RESERVED_MEMORY_TYPE, 0, 0);
-   device_path = image_path = memdp;
-   /*
-* 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;
-   } else {
-   assert(device_path && image_path);
-   }
-
-   ret = efi_setup_loaded_image(device_path, image_path, &image_obj,
-&loaded_image_info);
-   if (ret)
-   goto err_prepare;
+   efi_status_t ret;
 
/* 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);
+   ret = EFI_CALL(systab.boottime->open_protocol(
+   handle,
+   &efi_guid_loaded_image,
+   (void **)&loaded_image_info,
+   NULL, NULL,
+   EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
if (ret != EFI_SUCCESS)
-   goto err_prepare;
-
-   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;
-   }
+   goto err;
+   set_load_options(loaded_image_info, "bootargs");
 
/* we don't support much: */

env_set("efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported",
"{ro,boot}(blob)");
 
/* Call our payload! */
-   debug("%s: Jumping to 0x%p\n", __func__, image_obj->entry);
-   ret = EFI_CALL(efi_start_image(&image_obj->header, NULL, NULL));
+   ret = EFI_CALL(efi_start_image(handle, NULL, NULL));
 
-err_prepare:
-   /* image has returned, loaded-image obj goes *poof*: */
efi_restore_gd();
free(loaded_image_info->load_options);
-   efi_delete_handle(&image_obj->header);
-
-err_add_protocol:
-   if (mem_handle)
-   efi_delete_handle(mem_handle);
 
+err:
return