x86: use EFI calling convention for efi_main on x86_64
authorIvan Gorinov <ivan.gorinov@intel.com>
Thu, 14 Jun 2018 00:27:39 +0000 (17:27 -0700)
committerBin Meng <bmeng.cn@gmail.com>
Sun, 17 Jun 2018 13:16:04 +0000 (21:16 +0800)
UEFI specifies the calling convention used in Microsoft compilers;
first arguments of a function are passed in (%rcx, %rdx, %r8, %r9).

All other compilers use System V ABI by default, passing first integer
arguments of a function in (%rdi, %rsi, %rdx, %rcx, %r8, %r9).

These ABI also specify different sets of registers that must be preserved
across function calls (callee-saved).

GCC allows using the Microsoft calling convention by adding the ms_abi
attribute to a function declaration.

Current EFI implementation in U-Boot specifies EFIAPI for efi_main()
in the test apps but uses default calling convention in lib/efi.

Save efi_main() arguments in the startup code on x86_64;
use EFI calling convention for _relocate() on x86_64;
consistently use EFI calling convention for efi_main() everywhere.

Signed-off-by: Ivan Gorinov <ivan.gorinov@intel.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
arch/x86/lib/crt0_x86_64_efi.S
lib/efi/efi_app.c
lib/efi/efi_stub.c

index 989799fb4a196224804984b51d889b0acb580f8e..bb8d3cf8a9f4f2b2022f50d3a138e253e5573362 100644 (file)
@@ -3,7 +3,7 @@
  * crt0-efi-x86_64.S - x86_64 EFI startup code.
  * Copyright (C) 1999 Hewlett-Packard Co.
  * Contributed by David Mosberger <davidm@hpl.hp.com>.
- * Copyright (C) 2005 Intel Co.
+ * Copyright (C) 2005 Intel Corporation
  * Contributed by Fenghua Yu <fenghua.yu@intel.com>.
  *
  * All rights reserved.
        .globl _start
 _start:
        subq $8, %rsp
+
        pushq %rcx
        pushq %rdx
 
-0:
-       lea image_base(%rip), %rdi
-       lea _DYNAMIC(%rip), %rsi
+       mov %rcx, %r8
+       mov %rdx, %r9
+
+       lea image_base(%rip), %rcx
+       lea _DYNAMIC(%rip), %rdx
 
-       popq %rcx
-       popq %rdx
-       pushq %rcx
-       pushq %rdx
        call _relocate
 
-       popq %rdi
-       popq %rsi
+       popq %rdx
+       popq %rcx
+
+       testq %rax, %rax
+       jnz .exit
 
        call efi_main
+.exit:
        addq $8, %rsp
 
-.exit:
        ret
 
        /*
index c8280935c8418c1b7a7c4ba32e88e50de06d5c5f..3eb8eeb677fd90a8fbe55921333c9fba8c612918 100644 (file)
@@ -96,7 +96,8 @@ static void free_memory(struct efi_priv *priv)
  * U-Boot. If it returns, EFI will continue. Another way to get back to EFI
  * is via reset_cpu().
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+                            struct efi_system_table *sys_table)
 {
        struct efi_priv local_priv, *priv = &local_priv;
        efi_status_t ret;
index 09023a2f67a525ae6a83066de5c4c7b9e34e36b6..9deffe220febbc371641a9b13016be2c4c076803 100644 (file)
@@ -268,7 +268,8 @@ static void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type,
  * This function is called by our EFI start-up code. It handles running
  * U-Boot. If it returns, EFI will continue.
  */
-efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+efi_status_t EFIAPI efi_main(efi_handle_t image,
+                            struct efi_system_table *sys_table)
 {
        struct efi_priv local_priv, *priv = &local_priv;
        struct efi_boot_services *boot = sys_table->boottime;