x86: use _types.h headers in asm where available
[deliverable/linux.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_types.h>
7 #include <asm/pgtable_types.h>
8 #include <asm/processor-flags.h>
9
10 .code16
11 .section ".header", "a"
12
13 /* This should match the structure in wakeup.h */
14 .globl wakeup_header
15 wakeup_header:
16 video_mode: .short 0 /* Video mode number */
17 pmode_return: .byte 0x66, 0xea /* ljmpl */
18 .long 0 /* offset goes here */
19 .short __KERNEL_CS
20 pmode_cr0: .long 0 /* Saved %cr0 */
21 pmode_cr3: .long 0 /* Saved %cr3 */
22 pmode_cr4: .long 0 /* Saved %cr4 */
23 pmode_efer: .quad 0 /* Saved EFER */
24 pmode_gdt: .quad 0
25 realmode_flags: .long 0
26 real_magic: .long 0
27 trampoline_segment: .word 0
28 _pad1: .byte 0
29 wakeup_jmp: .byte 0xea /* ljmpw */
30 wakeup_jmp_off: .word 3f
31 wakeup_jmp_seg: .word 0
32 wakeup_gdt: .quad 0, 0, 0
33 signature: .long 0x51ee1111
34
35 .text
36 .globl _start
37 .code16
38 wakeup_code:
39 _start:
40 cli
41 cld
42
43 /* Apparently some dimwit BIOS programmers don't know how to
44 program a PM to RM transition, and we might end up here with
45 junk in the data segment descriptor registers. The only way
46 to repair that is to go into PM and fix it ourselves... */
47 movw $16, %cx
48 lgdtl %cs:wakeup_gdt
49 movl %cr0, %eax
50 orb $X86_CR0_PE, %al
51 movl %eax, %cr0
52 jmp 1f
53 1: ljmpw $8, $2f
54 2:
55 movw %cx, %ds
56 movw %cx, %es
57 movw %cx, %ss
58 movw %cx, %fs
59 movw %cx, %gs
60
61 andb $~X86_CR0_PE, %al
62 movl %eax, %cr0
63 jmp wakeup_jmp
64 3:
65 /* Set up segments */
66 movw %cs, %ax
67 movw %ax, %ds
68 movw %ax, %es
69 movw %ax, %ss
70 lidtl wakeup_idt
71
72 movl $wakeup_stack_end, %esp
73
74 /* Clear the EFLAGS */
75 pushl $0
76 popfl
77
78 /* Check header signature... */
79 movl signature, %eax
80 cmpl $0x51ee1111, %eax
81 jne bogus_real_magic
82
83 /* Check we really have everything... */
84 movl end_signature, %eax
85 cmpl $0x65a22c82, %eax
86 jne bogus_real_magic
87
88 /* Call the C code */
89 calll main
90
91 /* Do any other stuff... */
92
93 #ifndef CONFIG_64BIT
94 /* This could also be done in C code... */
95 movl pmode_cr3, %eax
96 movl %eax, %cr3
97
98 movl pmode_cr4, %ecx
99 jecxz 1f
100 movl %ecx, %cr4
101 1:
102 movl pmode_efer, %eax
103 movl pmode_efer + 4, %edx
104 movl %eax, %ecx
105 orl %edx, %ecx
106 jz 1f
107 movl $0xc0000080, %ecx
108 wrmsr
109 1:
110
111 lgdtl pmode_gdt
112
113 /* This really couldn't... */
114 movl pmode_cr0, %eax
115 movl %eax, %cr0
116 jmp pmode_return
117 #else
118 pushw $0
119 pushw trampoline_segment
120 pushw $0
121 lret
122 #endif
123
124 bogus_real_magic:
125 1:
126 hlt
127 jmp 1b
128
129 .data
130 .balign 8
131
132 /* This is the standard real-mode IDT */
133 wakeup_idt:
134 .word 0xffff /* limit */
135 .long 0 /* address */
136 .word 0
137
138 .globl HEAP, heap_end
139 HEAP:
140 .long wakeup_heap
141 heap_end:
142 .long wakeup_stack
143
144 .bss
145 wakeup_heap:
146 .space 2048
147 wakeup_stack:
148 .space 2048
149 wakeup_stack_end:
This page took 0.035995 seconds and 5 git commands to generate.