efi_loader: rearrange boottime service functions

To avoid forward declarations move efi_start_image() and efi_exit() down.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
Heinrich Schuchardt 2019-03-26 19:02:05 +01:00
parent 2c3ec28935
commit a115d56502

View file

@ -1744,115 +1744,6 @@ error:
return EFI_EXIT(ret);
}
/**
* efi_start_image() - call the entry point of an image
* @image_handle: handle of the image
* @exit_data_size: size of the buffer
* @exit_data: buffer to receive the exit data of the called image
*
* This function implements the StartImage service.
*
* See the Unified Extensible Firmware Interface (UEFI) specification for
* details.
*
* Return: status code
*/
efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
efi_uintn_t *exit_data_size,
u16 **exit_data)
{
struct efi_loaded_image_obj *image_obj =
(struct efi_loaded_image_obj *)image_handle;
efi_status_t ret;
EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
efi_is_direct_boot = false;
/* call the image! */
if (setjmp(&image_obj->exit_jmp)) {
/*
* We called the entry point of the child image with EFI_CALL
* in the lines below. The child image called the Exit() boot
* service efi_exit() which executed the long jump that brought
* us to the current line. This implies that the second half
* of the EFI_CALL macro has not been executed.
*/
#ifdef CONFIG_ARM
/*
* efi_exit() called efi_restore_gd(). We have to undo this
* otherwise __efi_entry_check() will put the wrong value into
* app_gd.
*/
gd = app_gd;
#endif
/*
* To get ready to call EFI_EXIT below we have to execute the
* missed out steps of EFI_CALL.
*/
assert(__efi_entry_check());
debug("%sEFI: %lu returned by started image\n",
__efi_nesting_dec(),
(unsigned long)((uintptr_t)image_obj->exit_status &
~EFI_ERROR_MASK));
return EFI_EXIT(image_obj->exit_status);
}
ret = EFI_CALL(image_obj->entry(image_handle, &systab));
/*
* Usually UEFI applications call Exit() instead of returning.
* But because the world doesn't consist of ponies and unicorns,
* we're happy to emulate that behavior on behalf of a payload
* that forgot.
*/
return EFI_CALL(systab.boottime->exit(image_handle, ret, 0, NULL));
}
/**
* efi_exit() - leave an EFI application or driver
* @image_handle: handle of the application or driver that is exiting
* @exit_status: status code
* @exit_data_size: size of the buffer in bytes
* @exit_data: buffer with data describing an error
*
* This function implements the Exit service.
*
* See the Unified Extensible Firmware Interface (UEFI) specification for
* details.
*
* Return: status code
*/
static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
efi_status_t exit_status,
efi_uintn_t exit_data_size,
u16 *exit_data)
{
/*
* TODO: We should call the unload procedure of the loaded
* image protocol.
*/
struct efi_loaded_image_obj *image_obj =
(struct efi_loaded_image_obj *)image_handle;
EFI_ENTRY("%p, %ld, %zu, %p", image_handle, exit_status,
exit_data_size, exit_data);
/* Make sure entry/exit counts for EFI world cross-overs match */
EFI_EXIT(exit_status);
/*
* But longjmp out with the U-Boot gd, not the application's, as
* the other end is a setjmp call inside EFI context.
*/
efi_restore_gd();
image_obj->exit_status = exit_status;
longjmp(&image_obj->exit_jmp, 1);
panic("EFI application exited");
}
/**
* efi_unload_image() - unload an EFI image
* @image_handle: handle of the image to be unloaded
@ -2720,6 +2611,115 @@ out:
return EFI_EXIT(r);
}
/**
* efi_start_image() - call the entry point of an image
* @image_handle: handle of the image
* @exit_data_size: size of the buffer
* @exit_data: buffer to receive the exit data of the called image
*
* This function implements the StartImage service.
*
* See the Unified Extensible Firmware Interface (UEFI) specification for
* details.
*
* Return: status code
*/
efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
efi_uintn_t *exit_data_size,
u16 **exit_data)
{
struct efi_loaded_image_obj *image_obj =
(struct efi_loaded_image_obj *)image_handle;
efi_status_t ret;
EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
efi_is_direct_boot = false;
/* call the image! */
if (setjmp(&image_obj->exit_jmp)) {
/*
* We called the entry point of the child image with EFI_CALL
* in the lines below. The child image called the Exit() boot
* service efi_exit() which executed the long jump that brought
* us to the current line. This implies that the second half
* of the EFI_CALL macro has not been executed.
*/
#ifdef CONFIG_ARM
/*
* efi_exit() called efi_restore_gd(). We have to undo this
* otherwise __efi_entry_check() will put the wrong value into
* app_gd.
*/
gd = app_gd;
#endif
/*
* To get ready to call EFI_EXIT below we have to execute the
* missed out steps of EFI_CALL.
*/
assert(__efi_entry_check());
debug("%sEFI: %lu returned by started image\n",
__efi_nesting_dec(),
(unsigned long)((uintptr_t)image_obj->exit_status &
~EFI_ERROR_MASK));
return EFI_EXIT(image_obj->exit_status);
}
ret = EFI_CALL(image_obj->entry(image_handle, &systab));
/*
* Usually UEFI applications call Exit() instead of returning.
* But because the world doesn't consist of ponies and unicorns,
* we're happy to emulate that behavior on behalf of a payload
* that forgot.
*/
return EFI_CALL(systab.boottime->exit(image_handle, ret, 0, NULL));
}
/**
* efi_exit() - leave an EFI application or driver
* @image_handle: handle of the application or driver that is exiting
* @exit_status: status code
* @exit_data_size: size of the buffer in bytes
* @exit_data: buffer with data describing an error
*
* This function implements the Exit service.
*
* See the Unified Extensible Firmware Interface (UEFI) specification for
* details.
*
* Return: status code
*/
static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
efi_status_t exit_status,
efi_uintn_t exit_data_size,
u16 *exit_data)
{
/*
* TODO: We should call the unload procedure of the loaded
* image protocol.
*/
struct efi_loaded_image_obj *image_obj =
(struct efi_loaded_image_obj *)image_handle;
EFI_ENTRY("%p, %ld, %zu, %p", image_handle, exit_status,
exit_data_size, exit_data);
/* Make sure entry/exit counts for EFI world cross-overs match */
EFI_EXIT(exit_status);
/*
* But longjmp out with the U-Boot gd, not the application's, as
* the other end is a setjmp call inside EFI context.
*/
efi_restore_gd();
image_obj->exit_status = exit_status;
longjmp(&image_obj->exit_jmp, 1);
panic("EFI application exited");
}
/**
* efi_handle_protocol() - get interface of a protocol on a handle
* @handle: handle on which the protocol shall be opened