32f0550
diff -up gnu-efi-3.0d/inc/ia32/pe.h.unwrap gnu-efi-3.0d/inc/ia32/pe.h
32f0550
--- gnu-efi-3.0d/inc/ia32/pe.h.unwrap	2008-03-10 14:38:18.000000000 -0400
32f0550
+++ gnu-efi-3.0d/inc/ia32/pe.h	2008-03-10 14:39:21.000000000 -0400
32f0550
@@ -588,4 +588,6 @@ typedef struct _IMAGE_IMPORT_DESCRIPTOR 
32f0550
     PIMAGE_THUNK_DATA FirstThunk;
32f0550
 } IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
32f0550
 
32f0550
+#define EFI_CALL(sym, argc) sym
32f0550
+
32f0550
 #endif
32f0550
diff -up gnu-efi-3.0d/inc/ia32/efibind.h.unwrap gnu-efi-3.0d/inc/ia32/efibind.h
32f0550
--- gnu-efi-3.0d/inc/ia32/efibind.h.unwrap	2008-03-10 14:34:58.000000000 -0400
32f0550
+++ gnu-efi-3.0d/inc/ia32/efibind.h	2008-03-10 14:35:49.000000000 -0400
32f0550
@@ -234,7 +234,22 @@ typedef uint32_t   UINTN;
32f0550
 // one big module.
32f0550
 //
32f0550
 
32f0550
-    #define EFI_DRIVER_ENTRY_POINT(InitFunction)
32f0550
+    #define EFI_DRIVER_ENTRY_POINT(InitFunction)    \
32f0550
+        UINTN                                       \
32f0550
+        InitializeDriver (                          \
32f0550
+            VOID    *ImageHandle,                   \
32f0550
+            VOID    *SystemTable                    \
32f0550
+            )                                       \
32f0550
+        {                                           \
32f0550
+            return InitFunction(ImageHandle,        \
32f0550
+                    SystemTable);                   \
32f0550
+        }                                           \
32f0550
+                                                    \
32f0550
+        EFI_STATUS efi_main(                        \
32f0550
+            EFI_HANDLE image,                       \
32f0550
+            EFI_SYSTEM_TABLE *systab                \
32f0550
+            ) __attribute__((weak,                  \
32f0550
+                    alias ("InitializeDriver")));
32f0550
 
32f0550
     #define LOAD_INTERNAL_DRIVER(_if, type, name, entry)    \
32f0550
             (_if)->LoadInternal(type, name, entry)
32f0550
diff -up gnu-efi-3.0d/inc/x86_64/pe.h.unwrap gnu-efi-3.0d/inc/x86_64/pe.h
32f0550
--- gnu-efi-3.0d/inc/x86_64/pe.h.unwrap	2008-03-10 14:37:23.000000000 -0400
32f0550
+++ gnu-efi-3.0d/inc/x86_64/pe.h	2008-03-10 14:38:08.000000000 -0400
32f0550
@@ -588,4 +588,184 @@ typedef struct _IMAGE_IMPORT_DESCRIPTOR 
32f0550
     PIMAGE_THUNK_DATA FirstThunk;
32f0550
 } IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
32f0550
 
32f0550
+#define alloc_lin_stack_frame(argc)         \
32f0550
+        "subq ($" #argc "-6)*8, %rsp\n\t"
32f0550
+#define free_lin_stack_frame(argc)          \
32f0550
+        "addq ($" #argc "-6)*8, %rsp\n\t"
32f0550
+
32f0550
+#define efi2lin_prolog                      \
32f0550
+        "push %rsi\n\t"                    \
32f0550
+        "push %rdi\n\t"
32f0550
+
32f0550
+#define efi2lin_epilog                      \
32f0550
+        "pop %rdi\n\t"                     \
32f0550
+        "pop %rsi\n\t"
32f0550
+
32f0550
+#define call_lin_func                       \
32f0550
+        "xor     %rax, %rax\n\t"          \
32f0550
+        "call   *%r10\n\t"
32f0550
+
32f0550
+#define efi2lin_efi_arg(n) "(" #n "+2)*8(%rsp)"
32f0550
+
32f0550
+#define efi2lin_arg1 "mov %rcx, %rdi\n\t"
32f0550
+#define efi2lin_arg2 "mov %rdx, %rsi\n\t"
32f0550
+#define efi2lin_arg3 "mov %r8, %rdx\n\t"
32f0550
+#define efi2lin_arg4 "mov %r9, %rcx\n\t"
32f0550
+#define efi2lin_arg5 "mov " efi2lin_efi_arg(5) ", %r8\n\t"
32f0550
+#define efi2lin_arg6 "mov " efi2lin_efi_arg(6) ", %r9\n\t"
32f0550
+
32f0550
+#define efi2lin0                            \
32f0550
+        efi2lin_prolog                      \
32f0550
+        call_lin_func                       \
32f0550
+        efi2lin_epilog                      \
32f0550
+	"ret\n\t"
32f0550
+
32f0550
+#define efi2lin1                            \
32f0550
+	efi2lin_prolog                      \
32f0550
+	efi2lin_arg1                        \
32f0550
+	call_lin_func                       \
32f0550
+	efi2lin_epilog                      \
32f0550
+	"ret\n\t"
32f0550
+
32f0550
+#define efi2lin2                            \
32f0550
+	efi2lin_prolog                      \
32f0550
+	efi2lin_arg1                        \
32f0550
+	efi2lin_arg2                        \
32f0550
+	call_lin_func                       \
32f0550
+	efi2lin_epilog                      \
32f0550
+	"ret\n\t"
32f0550
+
32f0550
+#define efi2lin3                            \
32f0550
+	efi2lin_prolog                      \
32f0550
+	efi2lin_arg1                        \
32f0550
+	efi2lin_arg2                        \
32f0550
+	efi2lin_arg3                        \
32f0550
+	call_lin_func                       \
32f0550
+	efi2lin_epilog                      \
32f0550
+	"ret\n\t"
32f0550
+
32f0550
+#define efi2lin4                            \
32f0550
+	efi2lin_prolog                      \
32f0550
+	efi2lin_arg1                        \
32f0550
+	efi2lin_arg2                        \
32f0550
+	efi2lin_arg3                        \
32f0550
+	efi2lin_arg4                        \
32f0550
+	call_lin_func                       \
32f0550
+	efi2lin_epilog                      \
32f0550
+	"ret\n\t"
32f0550
+
32f0550
+#define efi2lin5                            \
32f0550
+	efi2lin_prolog                      \
32f0550
+	efi2lin_arg1                        \
32f0550
+	efi2lin_arg2                        \
32f0550
+	efi2lin_arg3                        \
32f0550
+	efi2lin_arg4                        \
32f0550
+	efi2lin_arg5                        \
32f0550
+	call_lin_func                       \
32f0550
+	efi2lin_epilog                      \
32f0550
+	"ret\n\t"
32f0550
+
32f0550
+#define efi2lin6                            \
32f0550
+	efi2lin_prolog                      \
32f0550
+	efi2lin_arg1                        \
32f0550
+	efi2lin_arg2                        \
32f0550
+	efi2lin_arg3                        \
32f0550
+	efi2lin_arg4                        \
32f0550
+	efi2lin_arg5                        \
32f0550
+	efi2lin_arg6                        \
32f0550
+	call_lin_func                       \
32f0550
+	efi2lin_epilog                      \
32f0550
+	"ret\n\t"
32f0550
+
32f0550
+#define call_lin_func_args(n)               \
32f0550
+        "subq $(" #n "-6) *8, %rsp\n\t"    \
32f0550
+        call_lin_func                       \
32f0550
+        "addq $(" #n "-6) *8, %rsp\n\t"
32f0550
+
32f0550
+#define efi2lin_lin_arg(m, n) "(" #m "-1-" #n ")*8(%rsp)"
32f0550
+
32f0550
+#define efi2lin7                            \
32f0550
+	efi2lin_prolog                      \
32f0550
+                                            \
32f0550
+	efi2lin_arg1                        \
32f0550
+	efi2lin_arg2                        \
32f0550
+	efi2lin_arg3                        \
32f0550
+	efi2lin_arg4                        \
32f0550
+	efi2lin_arg5                        \
32f0550
+	efi2lin_arg6                        \
32f0550
+                                            \
32f0550
+	"# copy efidows argument 7 onto stack for Linux function" \
32f0550
+	"mov	" efi2lin_efi_arg(7) ", %r11   \n\t"   \
32f0550
+	"mov	%r11, " efi2lin_lin_arg(7,7) "\n\t"    \
32f0550
+                                            \
32f0550
+	call_lin_func_args(7)               \
32f0550
+	efi2lin_epilog                      \
32f0550
+	"ret\n\t"
32f0550
+
32f0550
+#define efi2lin8                            \
32f0550
+	efi2lin_prolog                      \
32f0550
+                                            \
32f0550
+	efi2lin_arg1                        \
32f0550
+	efi2lin_arg2                        \
32f0550
+	efi2lin_arg3                        \
32f0550
+	efi2lin_arg4                        \
32f0550
+	efi2lin_arg5                        \
32f0550
+	efi2lin_arg6                        \
32f0550
+                                            \
32f0550
+    	"# copy efidows arguments 7 and 8 onto stack for Linux function" \
32f0550
+	"mov	" efi2lin_efi_arg(7) ", %r11\n\t"      \
32f0550
+	"mov	%r11, " efi2lin_lin_arg(7,8) "\n\t"    \
32f0550
+	"mov	" efi2lin_efi_arg(8) ", %r11\n\t"      \
32f0550
+	"mov	%r11, " efi2lin_lin_arg(8,8) "\n\t"    \
32f0550
+                                            \
32f0550
+	call_lin_func_args(8)               \
32f0550
+	efi2lin_epilog                      \
32f0550
+	"ret\n\t"
32f0550
+
32f0550
+#define efi2lin9to12                                                    \
32f0550
+	efi2lin_prolog                                                  \
32f0550
+                                                                        \
32f0550
+	"# since we destroy rsi and rdi here, first copy efidows\n\t"   \
32f0550
+	"# arguments 7 through 12 onto stack for Linux function\n\t"    \
32f0550
+	"mov	%rcx, %r11		# save rcx\n\t"                 \
32f0550
+	"lea	" efi2lin_efi_arg(7) ", %rsi	# source (efidows arg 7 and up)\n\t" \
32f0550
+	"lea	" efi2lin_lin_arg(7,12) ", %rdi	# = destination\n\t" \
32f0550
+	"mov	$6, %rcx			# 6 arguments\n\t"      \
32f0550
+	"rep\n\t"                                                       \
32f0550
+	"movsq\n\t"                                                     \
32f0550
+	"mov	%r11, %rcx		# restore rcx\n\t"              \
32f0550
+                                                                        \
32f0550
+	efi2lin_arg1                                                    \
32f0550
+	efi2lin_arg2                                                    \
32f0550
+	efi2lin_arg3                                                    \
32f0550
+	efi2lin_arg4                                                    \
32f0550
+	efi2lin_arg5                                                    \
32f0550
+	efi2lin_arg6                                                    \
32f0550
+                                                                        \
32f0550
+	call_lin_func_args(12)                                          \
32f0550
+	efi2lin_epilog                                                  \
32f0550
+	"ret\n\t"
32f0550
+
32f0550
+#define efi2lin9 efi2lin9to12
32f0550
+#define efi2lin10 efi2lin9to12
32f0550
+#define efi2lin11 efi2lin9to12
32f0550
+#define efi2lin12 efi2lin9to12
32f0550
+
32f0550
+#define EFI_TOKEN_PASTE(a,b) a ## b
32f0550
+#define EFI_TOKEN_STRING(a) #a
32f0550
+#define EFI_CALL_NAME(sym) _efi_wrap_ ## sym
32f0550
+#define EFI_CALL(sym, argc)                                 \
32f0550
+    extern EFI_CALL_NAME(sym)();                            \
32f0550
+                                                            \
32f0550
+    __asm__ ("\n"                                           \
32f0550
+            ".globl " #sym "\n\t"                           \
32f0550
+            ".type\t" #sym ", @function\n"                  \
32f0550
+            #sym ":\n\t"                                    \
32f0550
+            "lea\t_efi_wrap_" #sym "@PLT, %r10\n\t"       \
32f0550
+            EFI_TOKEN_PASTE(efi2lin, argc)                  \
32f0550
+            ".size\t" #sym ", .-" #sym "\n\t"               \
32f0550
+            );                                              \
32f0550
+                                                            \
32f0550
+    EFI_STATUS EFI_CALL_NAME(sym)
32f0550
+
32f0550
 #endif
32f0550
diff -up gnu-efi-3.0d/inc/x86_64/efibind.h.unwrap gnu-efi-3.0d/inc/x86_64/efibind.h
32f0550
--- gnu-efi-3.0d/inc/x86_64/efibind.h.unwrap	2008-03-10 14:30:40.000000000 -0400
32f0550
+++ gnu-efi-3.0d/inc/x86_64/efibind.h	2008-03-10 14:35:51.000000000 -0400
32f0550
@@ -234,7 +234,22 @@ typedef uint64_t   UINTN;
32f0550
 // one big module.
32f0550
 //
32f0550
 
32f0550
-    #define EFI_DRIVER_ENTRY_POINT(InitFunction)
32f0550
+    #define EFI_DRIVER_ENTRY_POINT(InitFunction)    \
32f0550
+        UINTN                                       \
32f0550
+        InitializeDriver (                          \
32f0550
+            VOID    *ImageHandle,                   \
32f0550
+            VOID    *SystemTable                    \
32f0550
+            )                                       \
32f0550
+        {                                           \
32f0550
+            return InitFunction(ImageHandle,        \
32f0550
+                    SystemTable);                   \
32f0550
+        }                                           \
32f0550
+                                                    \
32f0550
+        EFI_STATUS efi_main(                        \
32f0550
+            EFI_HANDLE image,                       \
32f0550
+            EFI_SYSTEM_TABLE *systab                \
32f0550
+            ) __attribute__((weak,                  \
32f0550
+                    alias ("InitializeDriver")));
32f0550
 
32f0550
     #define LOAD_INTERNAL_DRIVER(_if, type, name, entry)    \
32f0550
             (_if)->LoadInternal(type, name, entry)
32f0550
diff -up gnu-efi-3.0d/inc/ia64/pe.h.unwrap gnu-efi-3.0d/inc/ia64/pe.h
32f0550
--- gnu-efi-3.0d/inc/ia64/pe.h.unwrap	2008-03-10 14:39:01.000000000 -0400
32f0550
+++ gnu-efi-3.0d/inc/ia64/pe.h	2008-03-10 14:39:20.000000000 -0400
32f0550
@@ -594,4 +594,6 @@ typedef struct _IMAGE_IMPORT_DESCRIPTOR 
32f0550
     PIMAGE_THUNK_DATA FirstThunk;
32f0550
 } IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
32f0550
 
32f0550
+#define EFI_CALL(sym, argc) sym
32f0550
+
32f0550
 #endif
32f0550
diff -up gnu-efi-3.0d/inc/ia64/efibind.h.unwrap gnu-efi-3.0d/inc/ia64/efibind.h
32f0550
--- gnu-efi-3.0d/inc/ia64/efibind.h.unwrap	2008-03-10 14:36:00.000000000 -0400
32f0550
+++ gnu-efi-3.0d/inc/ia64/efibind.h	2008-03-10 14:36:59.000000000 -0400
32f0550
@@ -187,7 +187,22 @@ void __mf (void);                       
32f0550
 // one big module.
32f0550
 //
32f0550
 
32f0550
-#define EFI_DRIVER_ENTRY_POINT(InitFunction)
32f0550
+#define EFI_DRIVER_ENTRY_POINT(InitFunction)    \
32f0550
+    UINTN                                       \
32f0550
+    InitializeDriver (                          \
32f0550
+        VOID    *ImageHandle,                   \
32f0550
+        VOID    *SystemTable                    \
32f0550
+        )                                       \
32f0550
+    {                                           \
32f0550
+        return InitFunction(ImageHandle,        \
32f0550
+                SystemTable);                   \
32f0550
+    }                                           \
32f0550
+                                                \
32f0550
+    EFI_STATUS efi_main(                        \
32f0550
+        EFI_HANDLE image,                       \
32f0550
+        EFI_SYSTEM_TABLE *systab                \
32f0550
+        ) __attribute__((weak,                  \
32f0550
+                alias ("InitializeDriver")));
32f0550
 
32f0550
 #define LOAD_INTERNAL_DRIVER(_if, type, name, entry)    \
32f0550
         (_if)->LoadInternal(type, name, entry)