Blob Blame History Raw
From 3f693b16c4f9992247e11c1f15cf0e06bbf69a93 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 26 Jul 2010 17:04:12 -0400
Subject: [PATCH] Add the routines to make callbacks work.

GCC on x86_64 now provides a function attribute "ms_abi" to generate
functions using the Windows x86_64 calling conventions.  These can be
used to write callback functions to be called from UEFI.
---
 Make.defaults        |    2 +-
 inc/ia32/efibind.h   |   18 +++++++++++++++++-
 inc/ia64/efibind.h   |   19 ++++++++++++++++++-
 inc/x86_64/efibind.h |   22 +++++++++++++++++-----
 4 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/Make.defaults b/Make.defaults
index 529d58c..2a981a1 100644
--- a/Make.defaults
+++ b/Make.defaults
@@ -59,7 +59,7 @@ ifeq ($(ARCH), ia32)
 endif
 
 ifeq ($(ARCH), x86_64)
-  CFLAGS += -DEFI_FUNCTION_WRAPPER -mno-red-zone 
+  CFLAGS += -mno-red-zone
   ifeq ($(HOSTARCH), ia32)
     ARCH3264 = -m64
   endif
diff --git a/inc/ia32/efibind.h b/inc/ia32/efibind.h
index 647a63e..0201ca1 100644
--- a/inc/ia32/efibind.h
+++ b/inc/ia32/efibind.h
@@ -234,7 +234,22 @@ typedef uint32_t   UINTN;
 // one big module.
 //
 
-    #define EFI_DRIVER_ENTRY_POINT(InitFunction)
+    #define EFI_DRIVER_ENTRY_POINT(InitFunction)    \
+        UINTN                                       \
+        InitializeDriver (                          \
+            VOID    *ImageHandle,                   \
+            VOID    *SystemTable                    \
+            )                                       \
+        {                                           \
+            return InitFunction(ImageHandle,        \
+                    SystemTable);                   \
+        }                                           \
+                                                    \
+        EFI_STATUS efi_main(                        \
+            EFI_HANDLE image,                       \
+            EFI_SYSTEM_TABLE *systab                \
+            ) __attribute__((weak,                  \
+                    alias ("InitializeDriver")));
 
     #define LOAD_INTERNAL_DRIVER(_if, type, name, entry)    \
             (_if)->LoadInternal(type, name, entry)
@@ -259,6 +274,7 @@ typedef uint32_t   UINTN;
 
 /* No efi call wrapper for IA32 architecture */
 #define uefi_call_wrapper(func, va_num, ...)	func(__VA_ARGS__)
+#define EFI_FUNCTION
 
 #ifdef _MSC_EXTENSIONS
 #pragma warning ( disable : 4731 )  // Suppress warnings about modification of EBP
diff --git a/inc/ia64/efibind.h b/inc/ia64/efibind.h
index 83ca529..aac83b3 100644
--- a/inc/ia64/efibind.h
+++ b/inc/ia64/efibind.h
@@ -182,7 +182,22 @@ void __mf (void);
 // one big module.
 //
 
-#define EFI_DRIVER_ENTRY_POINT(InitFunction)
+#define EFI_DRIVER_ENTRY_POINT(InitFunction)    \
+    UINTN                                       \
+    InitializeDriver (                          \
+        VOID    *ImageHandle,                   \
+        VOID    *SystemTable                    \
+        )                                       \
+    {                                           \
+        return InitFunction(ImageHandle,        \
+                SystemTable);                   \
+    }                                           \
+                                                \
+    EFI_STATUS efi_main(                        \
+        EFI_HANDLE image,                       \
+        EFI_SYSTEM_TABLE *systab                \
+        ) __attribute__((weak,                  \
+                alias ("InitializeDriver")));
 
 #define LOAD_INTERNAL_DRIVER(_if, type, name, entry)    \
         (_if)->LoadInternal(type, name, entry)
@@ -205,3 +220,4 @@ void __mf (void);
 
 /* No efi call wrapper for IA32 architecture */
 #define uefi_call_wrapper(func, va_num, ...)	func(__VA_ARGS__)
+#define EFI_FUNCTION
diff --git a/inc/x86_64/efibind.h b/inc/x86_64/efibind.h
index 1f8e735..9250973 100644
--- a/inc/x86_64/efibind.h
+++ b/inc/x86_64/efibind.h
@@ -234,7 +234,22 @@ typedef uint64_t   UINTN;
 // one big module.
 //
 
-    #define EFI_DRIVER_ENTRY_POINT(InitFunction)
+    #define EFI_DRIVER_ENTRY_POINT(InitFunction)    \
+        UINTN                                       \
+        InitializeDriver (                          \
+            VOID    *ImageHandle,                   \
+            VOID    *SystemTable                    \
+            )                                       \
+        {                                           \
+            return InitFunction(ImageHandle,        \
+                    SystemTable);                   \
+        }                                           \
+                                                    \
+        EFI_STATUS efi_main(                        \
+            EFI_HANDLE image,                       \
+            EFI_SYSTEM_TABLE *systab                \
+            ) __attribute__((weak,                  \
+                    alias ("InitializeDriver")));
 
     #define LOAD_INTERNAL_DRIVER(_if, type, name, entry)    \
             (_if)->LoadInternal(type, name, entry)
@@ -258,11 +273,8 @@ typedef uint64_t   UINTN;
 #endif
 
 /* for x86_64, EFI_FUNCTION_WRAPPER must be defined */
-#ifdef  EFI_FUNCTION_WRAPPER
 UINTN uefi_call_wrapper(void *func, unsigned long va_num, ...);
-#else
-#error "EFI_FUNCTION_WRAPPER must be defined for x86_64 architecture"
-#endif
+#define EFI_FUNCTION __attribute__((ms_abi))
 
 #ifdef _MSC_EXTENSIONS
 #pragma warning ( disable : 4731 )  // Suppress warnings about modification of EBP
-- 
1.7.6