]>
Commit | Line | Data |
---|---|---|
21a54a4d | 1 | #***************************************************************************** |
2 | #* | |
3 | #* Copyright (c) 2008, Intel Corporation | |
4 | #* All rights reserved. This program and the accompanying materials | |
5 | #* are licensed and made available under the terms and conditions of the BSD License | |
6 | #* which accompanies this distribution. The full text of the license may be found at | |
7 | #* http://opensource.org/licenses/bsd-license.php | |
8 | #* | |
9 | #* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
10 | #* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
11 | #* | |
12 | #* Module Name: | |
13 | #* | |
14 | #* Thunk.S | |
15 | #* | |
16 | #* Abstract: | |
17 | #* | |
18 | #* Real mode thunk | |
19 | #* | |
20 | #***************************************************************************** | |
21 | #include <EfiBind.h> | |
22 | ||
23 | ||
24 | ||
25 | .data | |
26 | ||
27 | .globl ASM_PFX(mCode16Size) | |
28 | ||
29 | .data | |
30 | mCode16Size: .long _Code16End - _Code16Addr | |
31 | ||
32 | ||
33 | NullSegSel: .quad 0 | |
34 | _16CsSegSel: | |
35 | .word -1 | |
36 | .word 0 | |
37 | .byte 0 | |
38 | .byte 0x9b | |
39 | .byte 0x8f #16-bit segment | |
40 | .byte 0 | |
41 | _16DsSegSel: | |
42 | .word -1 | |
43 | .word 0 | |
44 | .byte 0 | |
45 | .byte 0x93 | |
46 | .byte 0x8f #16-bit segment | |
47 | .byte 0 | |
48 | ||
49 | _16Gdtr: | |
50 | .word _16Gdtr - NullSegSel - 1 | |
51 | .long NullSegSel | |
52 | .code: | |
53 | ||
54 | #IA32_REGS STRUC 4t\r | |
55 | #_EDI DD ?\r | |
56 | #_ESI DD ?\r | |
57 | #_EBP DD ?\r | |
58 | #_ESP DD ?\r | |
59 | #_EBX DD ?\r | |
60 | #_EDX DD ?\r | |
61 | #_ECX DD ?\r | |
62 | #_EAX DD ?\r | |
63 | #_DS DW ?\r | |
64 | #_ES DW ?\r | |
65 | #_FS DW ?\r | |
66 | #_GS DW ?\r | |
67 | #_RFLAGS DQ ?\r | |
68 | #_EIP DD ?\r | |
69 | #_CS DW ?\r | |
70 | #_SS DW ?\r | |
71 | #IA32_REGS ENDS\r | |
72 | \r | |
73 | #_STK16 STRUC 1t\r | |
74 | #RetEip DD ?\r | |
75 | #RetCs DW ?\r | |
76 | #ThunkFlags DW ?\r | |
77 | #SavedGdtr FWORD ?\r | |
78 | #Resvd1 DW ?\r | |
79 | #SavedCr0 DD ?\r | |
80 | #SavedCr4 DD ?\r | |
81 | #_STK16 ENDS\r | |
82 | ||
83 | ASM_PFX(Thunk16): | |
84 | push %rbp | |
85 | push %rbx | |
86 | push %rsi | |
87 | push %rdi | |
88 | push %r12 | |
89 | push %r13 | |
90 | push %r14 | |
91 | push %r15 | |
92 | pushq %fs | |
93 | pushq %gs | |
94 | movl %ds,%r12d | |
95 | movl %es,%r13d | |
96 | movl %ss,%r14d | |
97 | mov %rsp,%r15 | |
98 | mov %rcx,%rsi | |
99 | movzwq 0x36(%rsi),%r10 #movzx r10, (IA32_REGS ptr [rsi])._SS | |
100 | xor %rdi,%rdi | |
101 | mov 0xc(%rsi),%edi #mov edi, (IA32_REGS ptr [rsi])._ESP | |
102 | add $0xffffffffffffffb0,%rdi #add rdi, - sizeof (IA32_REGS) - sizeof (_STK16) | |
103 | push %rdi | |
104 | imul $0x10,%r10,%rax | |
105 | add %rax,%rdi | |
106 | pushq $0xe #push sizeof (IA32_REGS) / 4 | |
107 | pop %rcx | |
108 | rep movsl %ds:(%rsi),%es:(%rdi) | |
109 | pop %rbx #rbx <- 16-bit stack offset | |
110 | lea Label,%eax #42 <_Thunk16+0x42> | |
111 | stos %eax,%es:(%rdi) | |
112 | movl %cs,%eax #return segment | |
113 | stos %ax,%es:(%rdi) | |
114 | mov %edx,%eax #THUNK Flags | |
115 | stos %ax,%es:(%rdi) | |
116 | sgdt 0x58(%rsp) #save GDTR | |
117 | mov 0x58(%rsp),%rax | |
118 | stos %rax,%es:(%rdi) | |
119 | mov %cr0,%rax #save CR0 | |
120 | mov %eax,%esi #esi <- CR0 to set | |
121 | stos %eax,%es:(%rdi) | |
122 | mov %cr4,%rax #save CR4 | |
123 | stos %eax,%es:(%rdi) | |
124 | sidt 0x58(%rsp) #save IDTR | |
125 | and $0x7ffffffe,%esi #clear PE & PG bits | |
126 | mov %r10,%rdi #rdi <- 16-bit stack segment | |
127 | shl $0x10,%r8 | |
128 | push %r8 #far jmp address | |
129 | lea Label_16Bit,%eax | |
130 | push %rax | |
131 | movw $0x8,0x4(%rsp) | |
132 | lgdt _16Gdtr #bugbug: may not match. | |
133 | lret | |
134 | Label_16Bit: | |
135 | .byte 0x66 | |
136 | movl $0xc0000080,%ecx | |
137 | mov %rsi,%cr0 #disable PE & PG | |
138 | rdmsr | |
139 | and $0xfe,%ah | |
140 | wrmsr #clear LME bit | |
141 | mov %cr4,%rax | |
142 | and $0xcf,%al #clear PAE & PSE | |
143 | mov %rax,%cr4 | |
144 | lret | |
145 | ||
146 | Label: | |
147 | xor %rax,%rax | |
148 | movl %ss,%eax | |
149 | shl $0x4,%eax | |
150 | add %esp,%eax | |
151 | mov %r15,%rsp | |
152 | lidt 0x58(%rsp) | |
153 | movl %r12d,%ds | |
154 | movl %r13d,%es | |
155 | movl %r14d,%ss | |
156 | popq %gs | |
157 | popq %fs | |
158 | pop %r15 | |
159 | pop %r14 | |
160 | pop %r13 | |
161 | pop %r12 | |
162 | pop %rdi | |
163 | pop %rsi | |
164 | pop %rbx | |
165 | pop %rbp | |
166 | retq | |
167 | ||
168 | ||
169 | .align 0x10 | |
170 | ||
171 | _Code16Addr: | |
172 | ASM_PFX(RealMode): | |
173 | movl %edi,%ss | |
174 | mov %bx,%sp #set up 16-bit stack | |
175 | .byte 0x2e | |
176 | .byte 0x0f | |
177 | .byte 0x01 | |
178 | .byte 0x1e\r | |
179 | .word _16Idtr - _Code16Addr #lidt _16Idtr\r | |
180 | .byte 0x66 | |
181 | .byte 0x61 #popad\r | |
182 | .byte 0x1f #pop ds\r | |
183 | .byte 0x07 #pop es | |
184 | popq %fs\r | |
185 | popq %gs\r | |
186 | add $0x8,%esp #skip RFLAGS\r | |
187 | .byte 0x67 #test [esp + 0eh], 1 | |
188 | .byte 0xf7 | |
189 | .byte 0x44 | |
190 | .byte 0x24 | |
191 | .byte 0x0e | |
192 | .byte 0x01 | |
193 | .byte 0x00 | |
194 | jz 1f | |
195 | pushfq #pushf, actually | |
196 | 1: | |
197 | .byte 0x0e #push cs | |
198 | .byte 0x68 #push /iw | |
199 | .word FarCallRet - _Code16Addr | |
200 | jz 2f | |
201 | .byte 0x66 | |
202 | ljmp *6(%esp) | |
203 | 2: | |
204 | .byte 0x66 | |
205 | ljmp *4(%esp) | |
206 | FarCallRet: | |
207 | .byte 0x66 | |
208 | push $0x00 #push a dword of zero | |
209 | .byte 0x66 | |
210 | pushf #pushfd, actually | |
211 | pushq %gs | |
212 | pushq %fs | |
213 | .byte 0x06 #push %es | |
214 | .byte 0x1e #push %ds | |
215 | .byte 0x66 | |
216 | .byte 0x60 | |
217 | cli | |
218 | .byte 0x66 #sizeof (IA32_REGS) = 13 * 4 = 52 | |
219 | lgdt 64(%esp) #lgdt (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr | |
220 | .byte 0x66 | |
221 | mov 76(%esp), %eax | |
222 | mov %rax, %cr4 | |
223 | .byte 0x66 | |
224 | mov $0xc0000080, %ecx | |
225 | rdmsr | |
226 | orb $1, %ah | |
227 | wrmsr | |
228 | .byte 0x66 | |
229 | mov 72(%esp), %eax | |
230 | mov %rax, %cr0 #restore CR0 | |
231 | .byte 0x66 | |
232 | ljmpl *52(%esp) | |
233 | ||
234 | _16Idtr: | |
235 | .word 0x3ff #FWORD (1 SHL 10) - 1 | |
236 | .byte 0x00 |