diff options
author | Pavel Machek <pavel@suse.cz> | 2008-04-10 23:28:10 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-17 17:41:37 +0200 |
commit | e44b7b7525ad9d43163ab5e60c784325419e0ea6 (patch) | |
tree | e2918917a97b4c9de4367e8778ed78afc762b9f8 /arch/x86/kernel/acpi/realmode/wakeup.S | |
parent | f49688d459c5eaa62db3597cbfd3cb13e361d415 (diff) |
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.S | 113 |
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: |