i386: prepare shared kernel/efi_stub.S
authorThomas Gleixner <tglx@linutronix.de>
Thu, 11 Oct 2007 09:12:06 +0000 (11:12 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 11 Oct 2007 09:12:06 +0000 (11:12 +0200)
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/i386/kernel/Makefile
arch/i386/kernel/efi_stub.S [deleted file]
arch/i386/kernel/efi_stub_32.S [new file with mode: 0644]

index 52b0041583cf8f20080d814b63f74935c959c151..f31a7f039e94630ffe5869f4f0528b0354192c46 100644 (file)
@@ -33,7 +33,7 @@ obj-$(CONFIG_KPROBES)         += kprobes.o
 obj-$(CONFIG_MODULES)          += module.o
 obj-y                          += sysenter.o vsyscall.o
 obj-$(CONFIG_ACPI_SRAT)        += srat_32.o
-obj-$(CONFIG_EFI)              += efi.o efi_stub.o
+obj-$(CONFIG_EFI)              += efi.o efi_stub_32.o
 obj-$(CONFIG_DOUBLEFAULT)      += doublefault.o
 obj-$(CONFIG_VM86)             += vm86_32.o
 obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
diff --git a/arch/i386/kernel/efi_stub.S b/arch/i386/kernel/efi_stub.S
deleted file mode 100644 (file)
index ef00bb7..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * EFI call stub for IA32.
- *
- * This stub allows us to make EFI calls in physical mode with interrupts
- * turned off.
- */
-
-#include <linux/linkage.h>
-#include <asm/page.h>
-
-/*
- * efi_call_phys(void *, ...) is a function with variable parameters.
- * All the callers of this function assure that all the parameters are 4-bytes.
- */
-
-/*
- * In gcc calling convention, EBX, ESP, EBP, ESI and EDI are all callee save.
- * So we'd better save all of them at the beginning of this function and restore
- * at the end no matter how many we use, because we can not assure EFI runtime
- * service functions will comply with gcc calling convention, too.
- */
-
-.text
-ENTRY(efi_call_phys)
-       /*
-        * 0. The function can only be called in Linux kernel. So CS has been
-        * set to 0x0010, DS and SS have been set to 0x0018. In EFI, I found
-        * the values of these registers are the same. And, the corresponding
-        * GDT entries are identical. So I will do nothing about segment reg
-        * and GDT, but change GDT base register in prelog and epilog.
-        */
-
-       /*
-        * 1. Now I am running with EIP = <physical address> + PAGE_OFFSET.
-        * But to make it smoothly switch from virtual mode to flat mode.
-        * The mapping of lower virtual memory has been created in prelog and
-        * epilog.
-        */
-       movl    $1f, %edx
-       subl    $__PAGE_OFFSET, %edx
-       jmp     *%edx
-1:
-
-       /*
-        * 2. Now on the top of stack is the return
-        * address in the caller of efi_call_phys(), then parameter 1,
-        * parameter 2, ..., param n. To make things easy, we save the return
-        * address of efi_call_phys in a global variable.
-        */
-       popl    %edx
-       movl    %edx, saved_return_addr
-       /* get the function pointer into ECX*/
-       popl    %ecx
-       movl    %ecx, efi_rt_function_ptr
-       movl    $2f, %edx
-       subl    $__PAGE_OFFSET, %edx
-       pushl   %edx
-
-       /*
-        * 3. Clear PG bit in %CR0.
-        */
-       movl    %cr0, %edx
-       andl    $0x7fffffff, %edx
-       movl    %edx, %cr0
-       jmp     1f
-1:
-
-       /*
-        * 4. Adjust stack pointer.
-        */
-       subl    $__PAGE_OFFSET, %esp
-
-       /*
-        * 5. Call the physical function.
-        */
-       jmp     *%ecx
-
-2:
-       /*
-        * 6. After EFI runtime service returns, control will return to
-        * following instruction. We'd better readjust stack pointer first.
-        */
-       addl    $__PAGE_OFFSET, %esp
-
-       /*
-        * 7. Restore PG bit
-        */
-       movl    %cr0, %edx
-       orl     $0x80000000, %edx
-       movl    %edx, %cr0
-       jmp     1f
-1:
-       /*
-        * 8. Now restore the virtual mode from flat mode by
-        * adding EIP with PAGE_OFFSET.
-        */
-       movl    $1f, %edx
-       jmp     *%edx
-1:
-
-       /*
-        * 9. Balance the stack. And because EAX contain the return value,
-        * we'd better not clobber it.
-        */
-       leal    efi_rt_function_ptr, %edx
-       movl    (%edx), %ecx
-       pushl   %ecx
-
-       /*
-        * 10. Push the saved return address onto the stack and return.
-        */
-       leal    saved_return_addr, %edx
-       movl    (%edx), %ecx
-       pushl   %ecx
-       ret
-.previous
-
-.data
-saved_return_addr:
-       .long 0
-efi_rt_function_ptr:
-       .long 0
diff --git a/arch/i386/kernel/efi_stub_32.S b/arch/i386/kernel/efi_stub_32.S
new file mode 100644 (file)
index 0000000..ef00bb7
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * EFI call stub for IA32.
+ *
+ * This stub allows us to make EFI calls in physical mode with interrupts
+ * turned off.
+ */
+
+#include <linux/linkage.h>
+#include <asm/page.h>
+
+/*
+ * efi_call_phys(void *, ...) is a function with variable parameters.
+ * All the callers of this function assure that all the parameters are 4-bytes.
+ */
+
+/*
+ * In gcc calling convention, EBX, ESP, EBP, ESI and EDI are all callee save.
+ * So we'd better save all of them at the beginning of this function and restore
+ * at the end no matter how many we use, because we can not assure EFI runtime
+ * service functions will comply with gcc calling convention, too.
+ */
+
+.text
+ENTRY(efi_call_phys)
+       /*
+        * 0. The function can only be called in Linux kernel. So CS has been
+        * set to 0x0010, DS and SS have been set to 0x0018. In EFI, I found
+        * the values of these registers are the same. And, the corresponding
+        * GDT entries are identical. So I will do nothing about segment reg
+        * and GDT, but change GDT base register in prelog and epilog.
+        */
+
+       /*
+        * 1. Now I am running with EIP = <physical address> + PAGE_OFFSET.
+        * But to make it smoothly switch from virtual mode to flat mode.
+        * The mapping of lower virtual memory has been created in prelog and
+        * epilog.
+        */
+       movl    $1f, %edx
+       subl    $__PAGE_OFFSET, %edx
+       jmp     *%edx
+1:
+
+       /*
+        * 2. Now on the top of stack is the return
+        * address in the caller of efi_call_phys(), then parameter 1,
+        * parameter 2, ..., param n. To make things easy, we save the return
+        * address of efi_call_phys in a global variable.
+        */
+       popl    %edx
+       movl    %edx, saved_return_addr
+       /* get the function pointer into ECX*/
+       popl    %ecx
+       movl    %ecx, efi_rt_function_ptr
+       movl    $2f, %edx
+       subl    $__PAGE_OFFSET, %edx
+       pushl   %edx
+
+       /*
+        * 3. Clear PG bit in %CR0.
+        */
+       movl    %cr0, %edx
+       andl    $0x7fffffff, %edx
+       movl    %edx, %cr0
+       jmp     1f
+1:
+
+       /*
+        * 4. Adjust stack pointer.
+        */
+       subl    $__PAGE_OFFSET, %esp
+
+       /*
+        * 5. Call the physical function.
+        */
+       jmp     *%ecx
+
+2:
+       /*
+        * 6. After EFI runtime service returns, control will return to
+        * following instruction. We'd better readjust stack pointer first.
+        */
+       addl    $__PAGE_OFFSET, %esp
+
+       /*
+        * 7. Restore PG bit
+        */
+       movl    %cr0, %edx
+       orl     $0x80000000, %edx
+       movl    %edx, %cr0
+       jmp     1f
+1:
+       /*
+        * 8. Now restore the virtual mode from flat mode by
+        * adding EIP with PAGE_OFFSET.
+        */
+       movl    $1f, %edx
+       jmp     *%edx
+1:
+
+       /*
+        * 9. Balance the stack. And because EAX contain the return value,
+        * we'd better not clobber it.
+        */
+       leal    efi_rt_function_ptr, %edx
+       movl    (%edx), %ecx
+       pushl   %ecx
+
+       /*
+        * 10. Push the saved return address onto the stack and return.
+        */
+       leal    saved_return_addr, %edx
+       movl    (%edx), %ecx
+       pushl   %ecx
+       ret
+.previous
+
+.data
+saved_return_addr:
+       .long 0
+efi_rt_function_ptr:
+       .long 0
This page took 0.027814 seconds and 5 git commands to generate.