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