x86 ACPI: fix resume from suspend to RAM on uniprocessor x86-64
[pandora-kernel.git] / arch / x86 / kernel / acpi / realmode / wakeup.S
1 /*
2  * ACPI wakeup real mode startup stub
3  */
4 #include <asm/segment.h>
5 #include <asm/msr-index.h>
6 #include <asm/page.h>
7 #include <asm/pgtable.h>
8
9         .code16
10         .section ".header", "a"
11
12 /* This should match the structure in wakeup.h */
13                 .globl  wakeup_header
14 wakeup_header:
15 video_mode:     .short  0       /* Video mode number */
16 pmode_return:   .byte   0x66, 0xea      /* ljmpl */
17                 .long   0       /* offset goes here */
18                 .short  __KERNEL_CS
19 pmode_cr0:      .long   0       /* Saved %cr0 */
20 pmode_cr3:      .long   0       /* Saved %cr3 */
21 pmode_cr4:      .long   0       /* Saved %cr4 */
22 pmode_efer:     .quad   0       /* Saved EFER */
23 pmode_gdt:      .quad   0
24 realmode_flags: .long   0
25 real_magic:     .long   0
26 trampoline_segment:     .word 0
27 signature:      .long   0x51ee1111
28
29         .text
30         .globl  _start
31         .code16
32 wakeup_code:
33 _start:
34         cli
35         cld
36
37         /* Set up segments */
38         movw    %cs, %ax
39         movw    %ax, %ds
40         movw    %ax, %es
41         movw    %ax, %ss
42
43         movl    $wakeup_stack_end, %esp
44
45         /* Clear the EFLAGS */
46         pushl   $0
47         popfl
48
49         /* Check header signature... */
50         movl    signature, %eax
51         cmpl    $0x51ee1111, %eax
52         jne     bogus_real_magic
53
54         /* Check we really have everything... */
55         movl    end_signature, %eax
56         cmpl    $0x65a22c82, %eax
57         jne     bogus_real_magic
58
59         /* Call the C code */
60         calll   main
61
62         /* Do any other stuff... */
63
64 #ifndef CONFIG_64BIT
65         /* This could also be done in C code... */
66         movl    pmode_cr3, %eax
67         movl    %eax, %cr3
68
69         movl    pmode_cr4, %ecx
70         jecxz   1f
71         movl    %ecx, %cr4
72 1:
73         movl    pmode_efer, %eax
74         movl    pmode_efer + 4, %edx
75         movl    %eax, %ecx
76         orl     %edx, %ecx
77         jz      1f
78         movl    $0xc0000080, %ecx
79         wrmsr
80 1:
81
82         lgdtl   pmode_gdt
83
84         /* This really couldn't... */
85         movl    pmode_cr0, %eax
86         movl    %eax, %cr0
87         jmp     pmode_return
88 #else
89         pushw   $0
90         pushw   trampoline_segment
91         pushw   $0
92         lret
93 #endif
94
95 bogus_real_magic:
96 1:
97         hlt
98         jmp     1b
99
100         .data
101         .balign 4
102         .globl  HEAP, heap_end
103 HEAP:
104         .long   wakeup_heap
105 heap_end:
106         .long   wakeup_stack
107
108         .bss
109 wakeup_heap:
110         .space  2048
111 wakeup_stack:
112         .space  2048
113 wakeup_stack_end: