1
2
3
4
5#include <linux/linkage.h>
6#include <asm/segment.h>
7#include <asm/msr-index.h>
8#include <asm/page_types.h>
9#include <asm/pgtable_types.h>
10#include <asm/processor-flags.h>
11#include "realmode.h"
12#include "wakeup.h"
13
14 .code16
15
16
17 .section ".data", "aw"
18
19 .balign 16
20SYM_DATA_START(wakeup_header)
21 video_mode: .short 0
22 pmode_entry: .long 0
23 pmode_cs: .short __KERNEL_CS
24 pmode_cr0: .long 0
25 pmode_cr3: .long 0
26 pmode_cr4: .long 0
27 pmode_efer: .quad 0
28 pmode_gdt: .quad 0
29 pmode_misc_en: .quad 0
30 pmode_behavior: .long 0
31 realmode_flags: .long 0
32 real_magic: .long 0
33 signature: .long WAKEUP_HEADER_SIGNATURE
34SYM_DATA_END(wakeup_header)
35
36 .text
37 .code16
38
39 .balign 16
40SYM_CODE_START(wakeup_start)
41 cli
42 cld
43
44 LJMPW_RM(3f)
453:
46
47
48
49
50 movw $16, %cx
51 lgdtl %cs:wakeup_gdt
52 movl %cr0, %eax
53 orb $X86_CR0_PE, %al
54 movl %eax, %cr0
55 ljmpw $8, $2f
562:
57 movw %cx, %ds
58 movw %cx, %es
59 movw %cx, %ss
60 movw %cx, %fs
61 movw %cx, %gs
62
63 andb $~X86_CR0_PE, %al
64 movl %eax, %cr0
65 LJMPW_RM(3f)
663:
67
68 movw %cs, %ax
69 movw %ax, %ss
70 movl $rm_stack_end, %esp
71 movw %ax, %ds
72 movw %ax, %es
73 movw %ax, %fs
74 movw %ax, %gs
75
76 lidtl .Lwakeup_idt
77
78
79 pushl $0
80 popfl
81
82
83 movl signature, %eax
84 cmpl $WAKEUP_HEADER_SIGNATURE, %eax
85 jne bogus_real_magic
86
87
88 movl end_signature, %eax
89 cmpl $REALMODE_END_SIGNATURE, %eax
90 jne bogus_real_magic
91
92
93 calll main
94
95
96
97 movl pmode_behavior, %edi
98 btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %edi
99 jnc 1f
100
101 movl pmode_misc_en, %eax
102 movl pmode_misc_en + 4, %edx
103 movl $MSR_IA32_MISC_ENABLE, %ecx
104 wrmsr
1051:
106
107
108
109#ifndef CONFIG_64BIT
110
111 movl pmode_cr3, %eax
112 movl %eax, %cr3
113
114 btl $WAKEUP_BEHAVIOR_RESTORE_CR4, %edi
115 jnc 1f
116 movl pmode_cr4, %eax
117 movl %eax, %cr4
1181:
119 btl $WAKEUP_BEHAVIOR_RESTORE_EFER, %edi
120 jnc 1f
121 movl pmode_efer, %eax
122 movl pmode_efer + 4, %edx
123 movl $MSR_EFER, %ecx
124 wrmsr
1251:
126
127 lgdtl pmode_gdt
128
129
130 movl pmode_entry, %eax
131 movl pmode_cr0, %ecx
132 movl %ecx, %cr0
133 ljmpl $__KERNEL_CS, $pa_startup_32
134
135#else
136 jmp trampoline_start
137#endif
138SYM_CODE_END(wakeup_start)
139
140bogus_real_magic:
1411:
142 hlt
143 jmp 1b
144
145 .section ".rodata","a"
146
147
148
149
150
151
152
153
154
155 .balign 16
156SYM_DATA_START(wakeup_gdt)
157 .word 3*8-1
158 .long pa_wakeup_gdt
159 .word 0
160
161 .word 0xffff
162 .long 0x9b000000 + pa_real_mode_base
163 .word 0x008f
164
165 .word 0xffff
166 .long 0x93000000 + pa_real_mode_base
167 .word 0x008f
168SYM_DATA_END(wakeup_gdt)
169
170 .section ".rodata","a"
171 .balign 8
172
173
174 .balign 16
175SYM_DATA_START_LOCAL(.Lwakeup_idt)
176 .word 0xffff
177 .long 0
178 .word 0
179SYM_DATA_END(.Lwakeup_idt)
180