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:
		
							parent
							
								
									2c3ec28935
								
							
						
					
					
						commit
						a115d56502
					
				| 
						 | 
					@ -1744,115 +1744,6 @@ error:
 | 
				
			||||||
	return EFI_EXIT(ret);
 | 
						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
 | 
					 * efi_unload_image() - unload an EFI image
 | 
				
			||||||
 * @image_handle: handle of the image to be unloaded
 | 
					 * @image_handle: handle of the image to be unloaded
 | 
				
			||||||
| 
						 | 
					@ -2720,6 +2611,115 @@ out:
 | 
				
			||||||
	return EFI_EXIT(r);
 | 
						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
 | 
					 * efi_handle_protocol() - get interface of a protocol on a handle
 | 
				
			||||||
 * @handle:             handle on which the protocol shall be opened
 | 
					 * @handle:             handle on which the protocol shall be opened
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue