xref: /openbmc/linux/drivers/firmware/efi/libstub/efi-stub-entry.c (revision 42c8ea3dca094ab82776ca706fb7a9cbe8ac3dc9)
1*42c8ea3dSArd Biesheuvel // SPDX-License-Identifier: GPL-2.0-only
2*42c8ea3dSArd Biesheuvel 
3*42c8ea3dSArd Biesheuvel #include <linux/efi.h>
4*42c8ea3dSArd Biesheuvel #include <asm/efi.h>
5*42c8ea3dSArd Biesheuvel 
6*42c8ea3dSArd Biesheuvel #include "efistub.h"
7*42c8ea3dSArd Biesheuvel 
8*42c8ea3dSArd Biesheuvel /*
9*42c8ea3dSArd Biesheuvel  * EFI entry point for the generic EFI stub used by ARM, arm64, RISC-V and
10*42c8ea3dSArd Biesheuvel  * LoongArch. This is the entrypoint that is described in the PE/COFF header
11*42c8ea3dSArd Biesheuvel  * of the core kernel.
12*42c8ea3dSArd Biesheuvel  */
13*42c8ea3dSArd Biesheuvel efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
14*42c8ea3dSArd Biesheuvel 				   efi_system_table_t *systab)
15*42c8ea3dSArd Biesheuvel {
16*42c8ea3dSArd Biesheuvel 	efi_loaded_image_t *image;
17*42c8ea3dSArd Biesheuvel 	efi_status_t status;
18*42c8ea3dSArd Biesheuvel 	unsigned long image_addr;
19*42c8ea3dSArd Biesheuvel 	unsigned long image_size = 0;
20*42c8ea3dSArd Biesheuvel 	/* addr/point and size pairs for memory management*/
21*42c8ea3dSArd Biesheuvel 	char *cmdline_ptr = NULL;
22*42c8ea3dSArd Biesheuvel 	efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
23*42c8ea3dSArd Biesheuvel 	unsigned long reserve_addr = 0;
24*42c8ea3dSArd Biesheuvel 	unsigned long reserve_size = 0;
25*42c8ea3dSArd Biesheuvel 
26*42c8ea3dSArd Biesheuvel 	WRITE_ONCE(efi_system_table, systab);
27*42c8ea3dSArd Biesheuvel 
28*42c8ea3dSArd Biesheuvel 	/* Check if we were booted by the EFI firmware */
29*42c8ea3dSArd Biesheuvel 	if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
30*42c8ea3dSArd Biesheuvel 		return EFI_INVALID_PARAMETER;
31*42c8ea3dSArd Biesheuvel 
32*42c8ea3dSArd Biesheuvel 	/*
33*42c8ea3dSArd Biesheuvel 	 * Get a handle to the loaded image protocol.  This is used to get
34*42c8ea3dSArd Biesheuvel 	 * information about the running image, such as size and the command
35*42c8ea3dSArd Biesheuvel 	 * line.
36*42c8ea3dSArd Biesheuvel 	 */
37*42c8ea3dSArd Biesheuvel 	status = efi_bs_call(handle_protocol, handle, &loaded_image_proto,
38*42c8ea3dSArd Biesheuvel 			     (void *)&image);
39*42c8ea3dSArd Biesheuvel 	if (status != EFI_SUCCESS) {
40*42c8ea3dSArd Biesheuvel 		efi_err("Failed to get loaded image protocol\n");
41*42c8ea3dSArd Biesheuvel 		return status;
42*42c8ea3dSArd Biesheuvel 	}
43*42c8ea3dSArd Biesheuvel 
44*42c8ea3dSArd Biesheuvel 	status = efi_handle_cmdline(image, &cmdline_ptr);
45*42c8ea3dSArd Biesheuvel 	if (status != EFI_SUCCESS)
46*42c8ea3dSArd Biesheuvel 		return status;
47*42c8ea3dSArd Biesheuvel 
48*42c8ea3dSArd Biesheuvel 	efi_info("Booting Linux Kernel...\n");
49*42c8ea3dSArd Biesheuvel 
50*42c8ea3dSArd Biesheuvel 	status = handle_kernel_image(&image_addr, &image_size,
51*42c8ea3dSArd Biesheuvel 				     &reserve_addr,
52*42c8ea3dSArd Biesheuvel 				     &reserve_size,
53*42c8ea3dSArd Biesheuvel 				     image, handle);
54*42c8ea3dSArd Biesheuvel 	if (status != EFI_SUCCESS) {
55*42c8ea3dSArd Biesheuvel 		efi_err("Failed to relocate kernel\n");
56*42c8ea3dSArd Biesheuvel 		return status;
57*42c8ea3dSArd Biesheuvel 	}
58*42c8ea3dSArd Biesheuvel 
59*42c8ea3dSArd Biesheuvel 	status = efi_stub_common(handle, image, image_addr, cmdline_ptr);
60*42c8ea3dSArd Biesheuvel 
61*42c8ea3dSArd Biesheuvel 	efi_free(image_size, image_addr);
62*42c8ea3dSArd Biesheuvel 	efi_free(reserve_size, reserve_addr);
63*42c8ea3dSArd Biesheuvel 
64*42c8ea3dSArd Biesheuvel 	return status;
65*42c8ea3dSArd Biesheuvel }
66