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