summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/acpi/realmode/wakeup.S
diff options
context:
space:
mode:
authorPavel Machek <pavel@suse.cz>2008-04-10 23:28:10 +0200
committerIngo Molnar <mingo@elte.hu>2008-04-17 17:41:37 +0200
commite44b7b7525ad9d43163ab5e60c784325419e0ea6 (patch)
treee2918917a97b4c9de4367e8778ed78afc762b9f8 /arch/x86/kernel/acpi/realmode/wakeup.S
parentx86: coding style fixes to arch/x86/kernel/acpi/sleep.c (diff)
downloadlinux-e44b7b7525ad9d43163ab5e60c784325419e0ea6.tar.xz
linux-e44b7b7525ad9d43163ab5e60c784325419e0ea6.zip
x86: move suspend wakeup code to C
Move wakeup code to .c, so that video mode setting code can be shared between boot and wakeup. Remove nasty assembly code in 64-bit case by re-using trampoline code. Stack setup was fixed to clear high 16bits of %esp, maybe that fixes some machines. .c code sharing and morse code was done H. Peter Anvin, Sam Ravnborg reviewed kbuild related stuff, and it seems okay to him. Rafael did some cleanups. [rjw: * Made the patch stop breaking compilation on x86-32 * Added arch/x86/kernel/acpi/sleep.h * Got rid of compiler warnings in arch/x86/kernel/acpi/sleep.c * Fixed 32-bit compilation on x86-64 systems * Added include/asm-x86/trampoline.h and fixed the non-SMP compilation on 64-bit x86 * Removed arch/x86/kernel/acpi/sleep_32.c which was not used * Fixed some breakage caused by the integration of smpboot.c done under us in the meantime] Signed-off-by: Pavel Machek <pavel@suse.cz> Signed-off-by: H. Peter Anvin <hpa@zytor.com> Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/acpi/realmode/wakeup.S')
-rw-r--r--arch/x86/kernel/acpi/realmode/wakeup.S113
1 files changed, 113 insertions, 0 deletions
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.S b/arch/x86/kernel/acpi/realmode/wakeup.S
new file mode 100644
index 000000000000..f9b77fb37e5b
--- /dev/null
+++ b/arch/x86/kernel/acpi/realmode/wakeup.S
@@ -0,0 +1,113 @@
+/*
+ * ACPI wakeup real mode startup stub
+ */
+#include <asm/segment.h>
+#include <asm/msr-index.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+ .code16
+ .section ".header", "a"
+
+/* This should match the structure in wakeup.h */
+ .globl wakeup_header
+wakeup_header:
+video_mode: .short 0 /* Video mode number */
+pmode_return: .byte 0x66, 0xea /* ljmpl */
+ .long 0 /* offset goes here */
+ .short __KERNEL_CS
+pmode_cr0: .long 0 /* Saved %cr0 */
+pmode_cr3: .long 0 /* Saved %cr3 */
+pmode_cr4: .long 0 /* Saved %cr4 */
+pmode_efer: .quad 0 /* Saved EFER */
+pmode_gdt: .quad 0
+realmode_flags: .long 0
+real_magic: .long 0
+trampoline_segment: .word 0
+signature: .long 0x51ee1111
+
+ .text
+ .globl _start
+ .code16
+wakeup_code:
+_start:
+ cli
+ cld
+
+ /* Set up segments */
+ movw %cs, %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %ss
+
+ movl $wakeup_stack_end, %esp
+
+ /* Clear the EFLAGS */
+ pushl $0
+ popfl
+
+ /* Check header signature... */
+ movl signature, %eax
+ cmpl $0x51ee1111, %eax
+ jne bogus_real_magic
+
+ /* Check we really have everything... */
+ movl end_signature, %eax
+ cmpl $0x65a22c82, %eax
+ jne bogus_real_magic
+
+ /* Call the C code */
+ calll main
+
+ /* Do any other stuff... */
+
+#ifndef CONFIG_64BIT
+ /* This could also be done in C code... */
+ movl pmode_cr3, %eax
+ movl %eax, %cr3
+
+ movl pmode_cr4, %ecx
+ jecxz 1f
+ movl %ecx, %cr4
+1:
+ movl pmode_efer, %eax
+ movl pmode_efer + 4, %edx
+ movl %eax, %ecx
+ orl %edx, %ecx
+ jz 1f
+ movl $0xc0000080, %ecx
+ wrmsr
+1:
+
+ lgdtl pmode_gdt
+
+ /* This really couldn't... */
+ movl pmode_cr0, %eax
+ movl %eax, %cr0
+ jmp pmode_return
+#else
+ pushw $0
+ pushw trampoline_segment
+ pushw $0
+ lret
+#endif
+
+bogus_real_magic:
+1:
+ hlt
+ jmp 1b
+
+ .data
+ .balign 4
+ .globl HEAP, heap_end
+HEAP:
+ .long wakeup_heap
+heap_end:
+ .long wakeup_stack
+
+ .bss
+wakeup_heap:
+ .space 2048
+wakeup_stack:
+ .space 2048
+wakeup_stack_end: