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
20 GLOBAL(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
34 END(wakeup_header)
35
36 .text
37 .code16
38
39 .balign 16
40 ENTRY(wakeup_start)
41 cli
42 cld
43
44 LJMPW_RM(3f)
45 3:
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
56 2:
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)
66 3:
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 wakeup_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
105 1:
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
118 1:
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
125 1:
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
138
139 bogus_real_magic:
140 1:
141 hlt
142 jmp 1b
143
144 .section ".rodata","a"
145
146
147
148
149
150
151
152
153
154 .balign 16
155 GLOBAL(wakeup_gdt)
156 .word 3*8-1
157 .long pa_wakeup_gdt
158 .word 0
159
160 .word 0xffff
161 .long 0x9b000000 + pa_real_mode_base
162 .word 0x008f
163
164 .word 0xffff
165 .long 0x93000000 + pa_real_mode_base
166 .word 0x008f
167 END(wakeup_gdt)
168
169 .section ".rodata","a"
170 .balign 8
171
172
173 .balign 16
174 GLOBAL(wakeup_idt)
175 .word 0xffff
176 .long 0
177 .word 0
178 END(wakeup_idt)