efi/libstub/arm: make efi_entry() an ordinary PE/COFF entrypoint
Subsystems (3)
Ard Biesheuvel
maintainerPATCH 1/1 efi/libstub/arm: make efi_entry() an ordinary PE/COFF entrypoint
Expose efi_entry() as the PE/COFF entrypoint directly, instead of jumping into a wrapper that fiddles with stack buffers and other stuff that the compiler is much better at. The only reason this code exists is to obtain a pointer to the base of the image, but we can get the same value from the loaded_image protocol, which we already need for other reasons anyway.
Update the return type as well, to make it consistent with what is required for a PE/COFF executable entrypoint.
---
Apologies to Atish for making him track a moving target, but this is another bit of cleanup work that I would like to merge before taking the RISC-V changes on top.
On RISC-V, I would expect efi_enter_kernel() to be implemented as a C routine that finds the hart id in the DT (which is passed as an argument), and pass it to the startup code of the kernel proper.
arch/arm/boot/compressed/efi-header.S | 2 +- arch/arm/boot/compressed/head.S | 44 +++----------- arch/arm64/kernel/efi-entry.S | 64 +++----------------- arch/arm64/kernel/efi-header.S | 2 +- drivers/firmware/efi/libstub/arm-stub.c | 37 +++++------ drivers/firmware/efi/libstub/arm32-stub.c | 1 + drivers/firmware/efi/libstub/arm64-stub.c | 3 +- 7 files changed, 42 insertions(+), 111 deletions(-)
arch/arm/boot/compressed/efi-header.S +1 -1
@@ -60,7 +60,7 @@ optional_header: .long __pecoff_code_size @ SizeOfCode .long __pecoff_data_size @ SizeOfInitializedData .long 0 @ SizeOfUninitializedData - .long efi_stub_entry - start @ AddressOfEntryPoint + .long efi_entry - start @ AddressOfEntryPoint .long start_offset @ BaseOfCode .long __pecoff_data_start - start @ BaseOfData
arch/arm/boot/compressed/head.S +8 -36
58 lines not on this page · raw message
arch/arm64/kernel/efi-entry.S +10 -54
85 lines not on this page · raw message
arch/arm64/kernel/efi-header.S +1 -1
@@ -27,7 +27,7 @@ optional_header: .long __initdata_begin - efi_header_end // SizeOfCode .long __pecoff_data_size // SizeOfInitializedData .long 0 // SizeOfUninitializedData - .long __efistub_entry - _head // AddressOfEntryPoint + .long __efistub_efi_entry - _head // AddressOfEntryPoint .long efi_header_end - _head // BaseOfCode extra_header_fields:
drivers/firmware/efi/libstub/arm-stub.c +20 -17
@@ -133,17 +133,20 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,unsigned long *reserve_size, unsigned long dram_base, efi_loaded_image_t *image); + +void __noreturn efi_enter_kernel (unsigned long entrypoint,unsigned long fdt); +/* * EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint * that is described in the PE/COFF header. Most of the code is the same * for both archictectures, with the arch-specific code provided in the * handle_kernel_image() function. */ -unsigned long efi_entry (void *handle,efi_system_table_t *sys_table_arg, -unsigned long *image_addr) +efi_status_t efi_entry (efi_handle_t handle,efi_system_table_t *sys_table_arg) {efi_loaded_image_t *image;efi_status_t status; +unsigned long image_addr;unsigned long image_size =0 ;unsigned long dram_base;/* addr/point and size pairs for memory management*/
@@ -153,7 +156,6 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table_arg,unsigned long fdt_size =0 ;char *cmdline_ptr =NULL ;int cmdline_size =0 ; -unsigned long new_fdt_addr;efi_guid_t loaded_image_proto =LOADED_IMAGE_PROTOCOL_GUID ;unsigned long reserve_addr =0 ;unsigned long reserve_size =0 ;
@@ -165,8 +167,10 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table_arg, sys_table = sys_table_arg;/* Check if we were booted by the EFI firmware */ -if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) +if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) { + status =EFI_INVALID_PARAMETER ; goto fail; + } status =check_platform_features ();if (status !=EFI_SUCCESS )
@@ -187,6 +191,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table_arg, dram_base =get_dram_base ();if (dram_base ==EFI_ERROR ) {pr_efi_err ("Failed to find DRAM base\n" ); + status =EFI_LOAD_ERROR ; goto fail; }
@@ -198,6 +203,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table_arg, cmdline_ptr =efi_convert_cmdline (image, &cmdline_size,ULONG_MAX );if (!cmdline_ptr) {pr_efi_err ("getting command line via LOADED_IMAGE_PROTOCOL\n" ); + status =EFI_OUT_OF_RESOURCES ; goto fail; }
@@ -213,7 +219,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table_arg, si =setup_graphics (); - status =handle_kernel_image (image_addr, &image_size, + status =handle_kernel_image (&image_addr, &image_size, &reserve_addr, &reserve_size, dram_base, image);
@@ -260,7 +266,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table_arg,pr_efi ("Generating empty DTB\n" );if (!noinitrd ()) { - max_addr =efi_get_max_initrd_addr (dram_base, *image_addr); + max_addr =efi_get_max_initrd_addr (dram_base, image_addr); status =efi_load_initrd_dev_path (&initrd_addr, &initrd_size, max_addr);if (status ==EFI_SUCCESS ) {
@@ -311,33 +317,30 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table_arg,install_memreserve_table (); - new_fdt_addr = fdt_addr; status =allocate_new_fdt_and_exit_boot (handle, - &new_fdt_addr,efi_get_max_fdt_addr (dram_base), + &fdt_addr,efi_get_max_fdt_addr (dram_base), initrd_addr, initrd_size, cmdline_ptr, fdt_addr, fdt_size); +if (status !=EFI_SUCCESS ) + goto fail_free_initrd; -/* -* If all went well, we need to return the FDT address to the -* calling function so it can be passed to kernel as part of -* the kernel boot protocol. -*/ -if (status ==EFI_SUCCESS ) -return new_fdt_addr; +efi_enter_kernel (image_addr, fdt_addr); +/* not reached */ +fail_free_initrd:pr_efi_err ("Failed to update FDT and exit boot services\n" );efi_free (initrd_size, initrd_addr);efi_free (fdt_size, fdt_addr); fail_free_image: -efi_free (image_size, *image_addr); +efi_free (image_size, image_addr);efi_free (reserve_size, reserve_addr); fail_free_cmdline:free_screen_info (si);efi_free (cmdline_size, (unsigned long )cmdline_ptr); fail: -return EFI_ERROR ; +return status; }/*
drivers/firmware/efi/libstub/arm32-stub.c +1 -0
@@ -227,6 +227,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,* Relocate the zImage, so that it appears in the lowest 128 MB * memory window. */ + *image_addr = image->image_base; *image_size = image->image_size; status =efi_relocate_kernel (image_addr, *image_size, *image_size, kernel_base +MAX_UNCOMP_KERNEL_SIZE ,0 ,0 );
drivers/firmware/efi/libstub/arm64-stub.c +1 -2
@@ -43,7 +43,6 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, {efi_status_t status;unsigned long kernel_size, kernel_memsize =0 ; -void *old_image_addr = (void *)*image_addr;unsigned long preferred_offset;u64 phys_seed =0 ;
@@ -141,7 +140,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, } *image_addr = *reserve_addr +TEXT_OFFSET ; } -memcpy ((void *)*image_addr, old_image_addr, kernel_size); +memcpy ((void *)*image_addr, image->image_base, kernel_size);return EFI_SUCCESS ; }
Signature · 1 line
2.17.1
Quoted 10 lines · Ard Biesheuvel
Expose
efi_entry()as the PE/COFF entrypoint directly, instead of jumping into a wrapper that fiddles with stack buffers and other stuff that the compiler is much better at. The only reason this code exists is to obtain a pointer to the base of the image, but we can get the same value from theloaded_imageprotocol, which we already need for other reasons anyway.Update the return type as well, to make it consistent with what is required for a PE/COFF executable entrypoint.
Quoted 8 lines
Signed-off-by Ard Biesheuvel <[email protected]>---
Apologies to Atish for making him track a moving target, but this is another
bit of cleanup work that I would like to merge before taking the RISC-V
changes on top.
And I thought I am done rebasing my patches ;). Jokes apart, this is actually much cleaner approach in retrieving image base and parsing DT compared to what I currently have for RISC-V.
Quoted 6 lines
On RISC-V, I would expect
efi_enter_kernel()to be implemented as a C routine
that finds the hart id in the DT (which is passed as an argument), and pass
it to the startup code of the kernel proper.
Yes. I probably won't need efi-entry.S for RISC-V at all which simplifies the RISC-V implementation. Yay!!
Is there a tree with this patch ? I tried to find it in your kernel.org repo but couldn't find it. As there are 3 efi related patch set in flight, I am not sure about the order in which they should be applied.
Quoted 402 lines
arch/arm/boot/compressed/efi-header.S | 2 +- arch/arm/boot/compressed/head.S | 44 +++----------- arch/arm64/kernel/efi-entry.S | 64 +++----------------- arch/arm64/kernel/efi-header.S | 2 +- drivers/firmware/efi/libstub/arm-stub.c | 37 +++++------ drivers/firmware/efi/libstub/arm32-stub.c | 1 + drivers/firmware/efi/libstub/arm64-stub.c | 3 +- 7 files changed, 42 insertions(+), 111 deletions(-)arch/arm/boot/compressed/efi-header.S +0
-0@@ -60,7 +60,7 @@ optional_header: .long __pecoff_code_size @ SizeOfCode .long __pecoff_data_size @SizeOfInitializedData
.long 0 @
SizeOfUninitializedDataarch/arm/boot/compressed/efi-header.S +0
-1- .long efi_stub_entry - start @AddressOfEntryPoint
arch/arm/boot/compressed/efi-header.S +1
-0+ .long efi_entry - start @AddressOfEntryPoint
arch/arm/boot/compressed/efi-header.S +0
-0.long start_offset @ BaseOfCode .long __pecoff_data_start - start @ BaseOfDataarch/arm/boot/compressed/head.S +0
-5@@ -1437,50 +1437,22 @@ __enter_kernel: reloc_code_end: #ifdef CONFIG_EFI_STUB - .align 2 -_start: .long start - . - -ENTRY(efi_stub_entry) - @ allocate space on stack for passing current zImageaddress
arch/arm/boot/compressed/head.S +0
-2- @ and for the EFI stub to return of new entry point of - @ zImage, as EFI stub may copy the kernel. Pointeraddress
arch/arm/boot/compressed/head.S +0
-1- @ is passed in r2. r0 and r1 are passed through fromthe
arch/arm/boot/compressed/head.S +0
-6- @ EFI firmware to efi_entry - adr ip, _start - ldr r3, [ip] - add r3, r3, ip - stmfd sp!, {r3, lr} - mov r2, sp @ pass zImage addressin r2
arch/arm/boot/compressed/head.S +0
-3- bl efi_entry - - @ Check for error return from EFI stub. r0 has FDTaddress
arch/arm/boot/compressed/head.S +3
-6- @ or error code. - cmn r0, #1 - beq efi_load_fail - - @ Preserve return value of efi_entry() in r4 - mov r4, r0 +ENTRY(efi_enter_kernel) + mov r4, r0 @ preserve entrypoint + mov r5, r1 @ preserve DT pointer bl cache_clean_flush bl cache_off @ Set parameters for booting zImage according to bootprotocol
arch/arm/boot/compressed/head.S +2
-7- @ put FDT address in r2, it was returned by efi_entry() - @ r1 is the machine type, and r0 needs to be 0 mov r0, #0 mov r1, #0xFFFFFFFF - mov r2, r4 + mov r2, r5 - @ Branch to (possibly) relocated zImage that is in [sp] - ldr lr, [sp] + @ Branch to (possibly) relocated zImage @ [r4] ldr ip, =start_offset - add lr, lr, ip - mov pc, lr @ no modeswitch
arch/arm/boot/compressed/head.S +3
-6- -efi_load_fail: - @ Return EFI_LOAD_ERROR to EFI firmware on error. - ldr r0, =0x80000001 - ldmfd sp!, {ip, pc} -ENDPROC(efi_stub_entry) + add r4, r4, ip + mov pc, r4 @ no mode switch +ENDPROC(efi_enter_kernel) #endif .alignarch/arm64/kernel/efi- renamed from arch/arm64/kernel/efi-entry.S +0
-0
entry.S
index304d5b02ca67..49e3b1ad1b36100644arch/arm64/kernel/efi-entry.S +0
-10@@ -10,55 +10,18 @@ #include <asm/assembler.h> -#define EFI_LOAD_ERROR 0x8000000000000001 - __INIT - /* - * We arrive here from the EFI boot manager with: - * - * * CPU in little-endian mode - * * MMU on with identity-mapped RAM - * * Icache and Dcache on - * - * We will most likely be running from some place other thanwhere
arch/arm64/kernel/efi-entry.S +0
-1- * we want to be. The kernel image wants to be placed at
TEXT_OFFSETarch/arm64/kernel/efi-entry.S +1
-26- * from start of RAM. - */ -ENTRY(entry) - /* - * Create a stack frame to save FP/LR with extra space - * for image_addr variable passed to efi_entry(). - */ - stp x29, x30, [sp, #-32]! - mov x29, sp - - /* - * Call efi_entry to do the real work. - * x0 and x1 are already set up by firmware. Current runtime - * address of image is calculated and passed via *image_addr. - * - * unsigned long efi_entry(void *handle, - * efi_system_table_t *sys_table, - * unsigned long *image_addr) ; - */ - adr_l x8, _text - add x2, sp, 16 - str x8, [x2] - bl efi_entry - cmn x0, #1 - b.eq efi_load_fail - +ENTRY(efi_enter_kernel) /* * efi_entry() will have copied the kernel image if necessaryand we
arch/arm64/kernel/efi-entry.S +0
-1- * return here with device tree address in x0 and the kernelentry
arch/arm64/kernel/efi-entry.S +0
-1- * point stored at *image_addr. Save those values in registerswhich
arch/arm64/kernel/efi-entry.S +1
-1- * are callee preserved. + * end up here with device tree address in x1 and the kernelentry
arch/arm64/kernel/efi-entry.S +4
-3+ * point stored in x0. Save those values in registers which are + * callee preserved. */ - mov x20, x0 // DTB address - ldr x0, [sp, #16] // relocated _text address + mov x20, x1 // DTB address ldr w21, =stext_offset - add x21, x0, x21 + add x21, x0, x21 // relocated Image address /* * Calculate size of the kernel Image (same for original andcopy).
arch/arm64/kernel/efi-entry.S +0
-0@@ -80,9 +43,8 @@ ENTRY(entry) * entries for the VA range of the current image, so nomaintenance is
arch/arm64/kernel/efi-entry.S +4
-11* necessary. */ - adr x0, entry - adr x1, entry_end - sub x1, x1, x0 + adr x0, efi_enter_kernel + mov x1, efi_enter_kernel_size bl __flush_dcache_area /* Turn off Dcache and MMU */@@ -110,11 +72,5 @@ ENTRY(entry) mov x2, xzr mov x3, xzr br x21 - -efi_load_fail: - mov x0, #EFI_LOAD_ERROR - ldp x29, x30, [sp], #32 - ret - -entry_end: -ENDPROC(entry) +ENDPROC(efi_enter_kernel) + .set efi_enter_kernel_size, . - efi_enter_kernelarch/arm64/kernel/efi- renamed from arch/arm64/kernel/efi-header.S +0
-0
header.S
indexa7cfacce3e15..40c704c5d3a5100644arch/arm64/kernel/efi-header.S +0
-0@@ -27,7 +27,7 @@ optional_header: .long __initdata_begin - efi_header_end // SizeOfCode .long __pecoff_data_size //SizeOfInitializedData
.long 0 //
SizeOfUninitializedDataarch/arm64/kernel/efi-header.S +0
-1- .long __efistub_entry - _head //AddressOfEntryPoint
arch/arm64/kernel/efi-header.S +1
-0+ .long __efistub_efi_entry - _head //AddressOfEntryPoint
arch/arm64/kernel/efi-header.S +0
-0.long efi_header_end - _head // BaseOfCode extra_header_fields:drivers/firmware/efi/libstub/arm-stub.c +3
-0@@ -133,17 +133,20 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, unsigned long *reserve_size, unsigned long dram_base, efi_loaded_image_t *image); + +void __noreturn efi_enter_kernel (unsigned long entrypoint,unsigned long fdt); +/* * EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint
* that is described in the PE/COFF header. Most of the code is the
same
* for both archictectures, with the arch-specific code provided in
the
*handle_kernel_image()function.
*/
-unsigned long efi_entry(void *handle,efi_system_table_t*sys_table_arg,drivers/firmware/efi/libstub/arm-stub.c +1
-1- unsigned long *image_addr) +efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t
*sys_table_arg)
{drivers/firmware/efi/libstub/arm-stub.c +1
-1efi_loaded_image_t *image;efi_status_t status; +unsigned long image_addr;unsigned long image_size =0 ;unsigned long dram_base;/* addr/point and size pairs for memory management*/ @@ -153,7 +156,6 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg, unsigned long fdt_size = 0;char *cmdline_ptr =NULL ;int cmdline_size =0 ; -unsigned long new_fdt_addr;efi_guid_t loaded_image_proto =LOADED_IMAGE_PROTOCOL_GUID ;unsigned long reserve_addr =0 ;drivers/firmware/efi/libstub/arm-stub.c +3
-1unsigned long reserve_size =0 ;@@ -165,8 +167,10 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg, sys_table = sys_table_arg;/* Check if we were booted by the EFI firmware */ -if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) +if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) { + status =EFI_INVALID_PARAMETER ; goto fail; + } status =check_platform_features ();drivers/firmware/efi/libstub/arm-stub.c +2
-0if (status !=EFI_SUCCESS )@@ -187,6 +191,7 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg, dram_base =get_dram_base ();if (dram_base ==EFI_ERROR ) {pr_efi_err ("Failed to find DRAM base\n" ); + status =EFI_LOAD_ERROR ; goto fail; }@@ -198,6 +203,7 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg, cmdline_ptr =efi_convert_cmdline (image, &cmdline_size,ULONG_MAX );if (!cmdline_ptr) {pr_efi_err ("getting command line via LOADED_IMAGE_PROTOCOL\n"); + status =EFI_OUT_OF_RESOURCES ;drivers/firmware/efi/libstub/arm-stub.c +1
-1goto fail; }@@ -213,7 +219,7 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg, si =setup_graphics (); - status = handle_kernel_image(image_addr, &image_size, + status = handle_kernel_image(&image_addr, &image_size, &reserve_addr, &reserve_size,drivers/firmware/efi/libstub/arm-stub.c +1
-1dram_base, image);@@ -260,7 +266,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table_arg,pr_efi ("Generating empty DTB\n" );if (!noinitrd ()) { - max_addr =efi_get_max_initrd_addr (dram_base, *image_addr); + max_addr =efi_get_max_initrd_addr (dram_base, image_addr);status = efi_load_initrd_dev_path(&initrd_addr,
&initrd_size,drivers/firmware/efi/libstub/arm-stub.c +8
-11max_addr);if (status ==EFI_SUCCESS ) {@@ -311,33 +317,30 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg,install_memreserve_table (); - new_fdt_addr = fdt_addr; status =allocate_new_fdt_and_exit_boot (handle, - &new_fdt_addr,efi_get_max_fdt_addr (dram_base), + &fdt_addr,efi_get_max_fdt_addr (dram_base), initrd_addr, initrd_size, cmdline_ptr, fdt_addr, fdt_size); +if (status !=EFI_SUCCESS ) + goto fail_free_initrd; -/* -* If all went well, we need to return the FDT address to the -* calling function so it can be passed to kernel as part of -* the kernel boot protocol. -*/ -if (status ==EFI_SUCCESS ) -return new_fdt_addr; +efi_enter_kernel (image_addr, fdt_addr); +/* not reached */ +fail_free_initrd:pr_efi_err ("Failed to update FDT and exit boot services\n" );efi_free (initrd_size, initrd_addr);efi_free (fdt_size, fdt_addr); fail_free_image: -efi_free (image_size, *image_addr); +efi_free (image_size, image_addr);efi_free (reserve_size, reserve_addr); fail_free_cmdline:free_screen_info (si);efi_free (cmdline_size, (unsigned long )cmdline_ptr); fail: -return EFI_ERROR ; +return status;}
/*
drivers/firmware/efi/libstub/arm32-stub.c +1
-0@@ -227,6 +227,7 @@ efi_status_t handle_kernel_image(unsigned long*image_addr, * Relocate the zImage, so that it appears in the lowest 128 MB * memory window. */ + *image_addr = image->image_base; *image_size = image->image_size; status = efi_relocate_kernel(image_addr, *image_size,
*image_size,
kernel_base+MAX_UNCOMP_KERNEL_SIZE, 0, 0);drivers/firmware/efi/libstub/arm64-stub.c +1
-2@@ -43,7 +43,6 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, {efi_status_t status;unsigned long kernel_size, kernel_memsize =0 ; -void *old_image_addr = (void *)*image_addr;unsigned long preferred_offset;u64 phys_seed =0 ;@@ -141,7 +140,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, } *image_addr = *reserve_addr +TEXT_OFFSET ; } -memcpy ((void *)*image_addr, old_image_addr, kernel_size); +memcpy ((void *)*image_addr, image->image_base, kernel_size);return EFI_SUCCESS ;}
Signature · 2 lines
Regards, Atish
Ard Biesheuvel
maintainerQuoted 33 lines · Atish Patra
Quoted 10 lines · Ard Biesheuvel
Expose
efi_entry()as the PE/COFF entrypoint directly, instead of jumping into a wrapper that fiddles with stack buffers and other stuff that the compiler is much better at. The only reason this code exists is to obtain a pointer to the base of the image, but we can get the same value from theloaded_imageprotocol, which we already need for other reasons anyway.Update the return type as well, to make it consistent with what is required for a PE/COFF executable entrypoint.
Quoted 8 lines
Signed-off-by Ard Biesheuvel <[email protected]>---
Apologies to Atish for making him track a moving target, but this is another
bit of cleanup work that I would like to merge before taking the RISC-V
changes on top.And I thought I am done rebasing my patches ;). Jokes apart, this is actually much cleaner approach in retrieving image base and parsing DT compared to what I currently have for RISC-V.
Quoted 6 lines
On RISC-V, I would expect
efi_enter_kernel()to be implemented as a C routine
that finds the hart id in the DT (which is passed as an argument), and pass
it to the startup code of the kernel proper.
Quoted 3 lines
Yes. I probably won't need
efi-entry.Sfor RISC-V at all which simplifies the RISC-V implementation. Yay!!
Glad to hear that.
Quoted 5 lines
Is there a tree with this patch ? I tried to find it in your kernel.org repo but couldn't find it. As there are 3 efi related patch set in flight, I am not sure about the order in which they should be applied.
Please rebase onto
https://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git/log/?h=next
Quoted 406 lines
Quoted 401 lines
arch/arm/boot/compressed/efi-header.S | 2 +- arch/arm/boot/compressed/head.S | 44 +++----------- arch/arm64/kernel/efi-entry.S | 64 +++----------------- arch/arm64/kernel/efi-header.S | 2 +- drivers/firmware/efi/libstub/arm-stub.c | 37 +++++------ drivers/firmware/efi/libstub/arm32-stub.c | 1 + drivers/firmware/efi/libstub/arm64-stub.c | 3 +- 7 files changed, 42 insertions(+), 111 deletions(-)arch/arm/boot/compressed/efi-header.S +0
-0@@ -60,7 +60,7 @@ optional_header: .long __pecoff_code_size @ SizeOfCode .long __pecoff_data_size @SizeOfInitializedData
.long 0 @
SizeOfUninitializedData
- .longefi_stub_entry- start @
AddressOfEntryPoint
+ .longefi_entry- start @
AddressOfEntryPoint.long start_offset @ BaseOfCode .long __pecoff_data_start - start @ BaseOfDataarch/arm/boot/compressed/head.S +0
-5@@ -1437,50 +1437,22 @@ __enter_kernel: reloc_code_end: #ifdef CONFIG_EFI_STUB - .align 2 -_start: .long start - . - -ENTRY(efi_stub_entry) - @ allocate space on stack for passing current zImageaddress
arch/arm/boot/compressed/head.S +0
-2- @ and for the EFI stub to return of new entry point of - @ zImage, as EFI stub may copy the kernel. Pointeraddress
- @ is passed in r2. r0 and r1 are passed through from
thearch/arm/boot/compressed/head.S +0
-6- @ EFI firmware to efi_entry - adr ip, _start - ldr r3, [ip] - add r3, r3, ip - stmfd sp!, {r3, lr} - mov r2, sp @ pass zImage addressin r2
arch/arm/boot/compressed/head.S +0
-3- bl efi_entry - - @ Check for error return from EFI stub. r0 has FDTaddress
arch/arm/boot/compressed/head.S +3
-6- @ or error code. - cmn r0, #1 - beq efi_load_fail - - @ Preserve return value of efi_entry() in r4 - mov r4, r0 +ENTRY(efi_enter_kernel) + mov r4, r0 @ preserve entrypoint + mov r5, r1 @ preserve DT pointer bl cache_clean_flush bl cache_off @ Set parameters for booting zImage according to bootprotocol
arch/arm/boot/compressed/head.S +2
-7- @ put FDT address in r2, it was returned by efi_entry() - @ r1 is the machine type, and r0 needs to be 0 mov r0, #0 mov r1, #0xFFFFFFFF - mov r2, r4 + mov r2, r5 - @ Branch to (possibly) relocated zImage that is in [sp] - ldr lr, [sp] + @ Branch to (possibly) relocated zImage @ [r4] ldr ip, =start_offset - add lr, lr, ip - mov pc, lr @ no modeswitch
arch/arm/boot/compressed/head.S +3
-6- -efi_load_fail: - @ Return EFI_LOAD_ERROR to EFI firmware on error. - ldr r0, =0x80000001 - ldmfd sp!, {ip, pc} -ENDPROC(efi_stub_entry) + add r4, r4, ip + mov pc, r4 @ no mode switch +ENDPROC(efi_enter_kernel) #endif .alignarch/arm64/kernel/efi- renamed from arch/arm64/kernel/efi-entry.S +0
-0
entry.S
index304d5b02ca67..49e3b1ad1b36100644arch/arm64/kernel/efi-entry.S +0
-10@@ -10,55 +10,18 @@ #include <asm/assembler.h> -#define EFI_LOAD_ERROR 0x8000000000000001 - __INIT - /* - * We arrive here from the EFI boot manager with: - * - * * CPU in little-endian mode - * * MMU on with identity-mapped RAM - * * Icache and Dcache on - * - * We will most likely be running from some place other thanwhere
- * we want to be. The kernel image wants to be placed atTEXT_OFFSETarch/arm64/kernel/efi-entry.S +1
-26- * from start of RAM. - */ -ENTRY(entry) - /* - * Create a stack frame to save FP/LR with extra space - * for image_addr variable passed to efi_entry(). - */ - stp x29, x30, [sp, #-32]! - mov x29, sp - - /* - * Call efi_entry to do the real work. - * x0 and x1 are already set up by firmware. Current runtime - * address of image is calculated and passed via *image_addr. - * - * unsigned long efi_entry(void *handle, - * efi_system_table_t *sys_table, - * unsigned long *image_addr) ; - */ - adr_l x8, _text - add x2, sp, 16 - str x8, [x2] - bl efi_entry - cmn x0, #1 - b.eq efi_load_fail - +ENTRY(efi_enter_kernel) /* * efi_entry() will have copied the kernel image if necessaryand we
- * return here with device tree address in x0 and the kernel
entry
- * point stored at*image_addr. Save those values in registers
whicharch/arm64/kernel/efi-entry.S +1
-1- * are callee preserved. + * end up here with device tree address in x1 and the kernelentry
arch/arm64/kernel/efi-entry.S +4
-3+ * point stored in x0. Save those values in registers which are + * callee preserved. */ - mov x20, x0 // DTB address - ldr x0, [sp, #16] // relocated _text address + mov x20, x1 // DTB address ldr w21, =stext_offset - add x21, x0, x21 + add x21, x0, x21 // relocated Image address /* * Calculate size of the kernel Image (same for original andcopy).
arch/arm64/kernel/efi-entry.S +0
-0@@ -80,9 +43,8 @@ ENTRY(entry) * entries for the VA range of the current image, so nomaintenance is
* necessary.
*/arch/arm64/kernel/efi-entry.S +4
-11- adr x0, entry - adr x1, entry_end - sub x1, x1, x0 + adr x0, efi_enter_kernel + mov x1, efi_enter_kernel_size bl __flush_dcache_area /* Turn off Dcache and MMU */@@ -110,11 +72,5 @@ ENTRY(entry) mov x2, xzr mov x3, xzr br x21 - -efi_load_fail: - mov x0, #EFI_LOAD_ERROR - ldp x29, x30, [sp], #32 - ret - -entry_end: -ENDPROC(entry) +ENDPROC(efi_enter_kernel) + .set efi_enter_kernel_size, . - efi_enter_kernelarch/arm64/kernel/efi- renamed from arch/arm64/kernel/efi-header.S +0
-0
header.S
indexa7cfacce3e15..40c704c5d3a5100644arch/arm64/kernel/efi-header.S +0
-0@@ -27,7 +27,7 @@ optional_header: .long __initdata_begin - efi_header_end // SizeOfCode .long __pecoff_data_size //SizeOfInitializedData
.long 0 //
SizeOfUninitializedData
- .long__efistub_entry-_head//
AddressOfEntryPoint
+ .long__efistub_efi_entry-_head//
AddressOfEntryPoint
.longefi_header_end-_head// BaseOfCode
extra_header_fields:drivers/firmware/efi/libstub/arm-stub.c +3
-0@@ -133,17 +133,20 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, unsigned long *reserve_size, unsigned long dram_base, efi_loaded_image_t *image); + +void __noreturn efi_enter_kernel (unsigned long entrypoint,unsigned long fdt); +/* * EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint
* that is described in the PE/COFF header. Most of the code is the
same
* for both archictectures, with the arch-specific code provided in
the
*handle_kernel_image()function.
*/
-unsigned long efi_entry(void *handle,efi_system_table_t*sys_table_arg,drivers/firmware/efi/libstub/arm-stub.c +1
-1- unsigned long *image_addr) +efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t
*sys_table_arg){ efi_loaded_image_t *image; efi_status_t status;drivers/firmware/efi/libstub/arm-stub.c +1
-1+unsigned long image_addr;unsigned long image_size =0 ;unsigned long dram_base;/* addr/point and size pairs for memory management*/ @@ -153,7 +156,6 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg, unsigned long fdt_size = 0;char *cmdline_ptr =NULL ;int cmdline_size =0 ; -unsigned long new_fdt_addr;efi_guid_t loaded_image_proto =LOADED_IMAGE_PROTOCOL_GUID ;unsigned long reserve_addr =0 ;unsigned long reserve_size = 0;drivers/firmware/efi/libstub/arm-stub.c +3
-1@@ -165,8 +167,10 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg, sys_table = sys_table_arg;/* Check if we were booted by the EFI firmware */ -if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) +if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) { + status =EFI_INVALID_PARAMETER ; goto fail; + } status =check_platform_features ();if (status != EFI_SUCCESS)drivers/firmware/efi/libstub/arm-stub.c +2
-0@@ -187,6 +191,7 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg, dram_base =get_dram_base ();if (dram_base ==EFI_ERROR ) {pr_efi_err ("Failed to find DRAM base\n" ); + status =EFI_LOAD_ERROR ; goto fail; }@@ -198,6 +203,7 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg, cmdline_ptr =efi_convert_cmdline (image, &cmdline_size,ULONG_MAX );if (!cmdline_ptr) {pr_efi_err ("getting command line via LOADED_IMAGE_PROTOCOL\n"); + status =EFI_OUT_OF_RESOURCES ;goto fail; }drivers/firmware/efi/libstub/arm-stub.c +1
-1@@ -213,7 +219,7 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg, si =setup_graphics (); - status = handle_kernel_image(image_addr, &image_size, + status = handle_kernel_image(&image_addr, &image_size, &reserve_addr, &reserve_size,dram_base, image);drivers/firmware/efi/libstub/arm-stub.c +1
-1@@ -260,7 +266,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table_arg,pr_efi ("Generating empty DTB\n" );if (!noinitrd ()) { - max_addr =efi_get_max_initrd_addr (dram_base, *image_addr); + max_addr =efi_get_max_initrd_addr (dram_base, image_addr);status = efi_load_initrd_dev_path(&initrd_addr,
&initrd_size,max_addr); if (status == EFI_SUCCESS) {drivers/firmware/efi/libstub/arm-stub.c +8
-11@@ -311,33 +317,30 @@ unsigned long efi_entry(void *handle,efi_system_table_t *sys_table_arg,install_memreserve_table (); - new_fdt_addr = fdt_addr; status =allocate_new_fdt_and_exit_boot (handle, - &new_fdt_addr,efi_get_max_fdt_addr (dram_base), + &fdt_addr,efi_get_max_fdt_addr (dram_base), initrd_addr, initrd_size, cmdline_ptr, fdt_addr, fdt_size); +if (status !=EFI_SUCCESS ) + goto fail_free_initrd; -/* -* If all went well, we need to return the FDT address to the -* calling function so it can be passed to kernel as part of -* the kernel boot protocol. -*/ -if (status ==EFI_SUCCESS ) -return new_fdt_addr; +efi_enter_kernel (image_addr, fdt_addr); +/* not reached */ +fail_free_initrd:pr_efi_err ("Failed to update FDT and exit boot services\n" );efi_free (initrd_size, initrd_addr);efi_free (fdt_size, fdt_addr); fail_free_image: -efi_free (image_size, *image_addr); +efi_free (image_size, image_addr);efi_free (reserve_size, reserve_addr); fail_free_cmdline:free_screen_info (si);efi_free (cmdline_size, (unsigned long )cmdline_ptr); fail: -return EFI_ERROR ; +return status;}
/*
drivers/firmware/efi/libstub/arm32-stub.c +1
-0@@ -227,6 +227,7 @@ efi_status_t handle_kernel_image(unsigned long*image_addr, * Relocate the zImage, so that it appears in the lowest 128 MB * memory window. */ + *image_addr = image->image_base; *image_size = image->image_size; status = efi_relocate_kernel(image_addr, *image_size,
*image_size,
kernel_base+MAX_UNCOMP_KERNEL_SIZE, 0, 0);drivers/firmware/efi/libstub/arm64-stub.c +1
-2@@ -43,7 +43,6 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, {efi_status_t status;unsigned long kernel_size, kernel_memsize =0 ; -void *old_image_addr = (void *)*image_addr;unsigned long preferred_offset;u64 phys_seed =0 ;@@ -141,7 +140,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, } *image_addr = *reserve_addr +TEXT_OFFSET ; } -memcpy ((void *)*image_addr, old_image_addr, kernel_size); +memcpy ((void *)*image_addr, image->image_base, kernel_size);return EFI_SUCCESS ;Quoted 1 line
}
--
Regards,
Atish