]> git.proxmox.com Git - mirror_edk2.git/blob - 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
1 #*****************************************************************************
2 #*
3 #* Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
4 #* 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
55 #_EDI DD ?
56 #_ESI DD ?
57 #_EBP DD ?
58 #_ESP DD ?
59 #_EBX DD ?
60 #_EDX DD ?
61 #_ECX DD ?
62 #_EAX DD ?
63 #_DS DW ?
64 #_ES DW ?
65 #_FS DW ?
66 #_GS DW ?
67 #_RFLAGS DQ ?
68 #_EIP DD ?
69 #_CS DW ?
70 #_SS DW ?
71 #IA32_REGS ENDS
72
73 #_STK16 STRUC 1t
74 #RetEip DD ?
75 #RetCs DW ?
76 #ThunkFlags DW ?
77 #SavedGdtr FWORD ?
78 #Resvd1 DW ?
79 #SavedCr0 DD ?
80 #SavedCr4 DD ?
81 #_STK16 ENDS
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 #; copy eflags to stack frame
110 mov -16(%rsi), %rax
111 mov %rax, -80(%rsi)
112 pop %rbx #rbx <- 16-bit stack offset
113 lea Label,%eax #42 <_Thunk16+0x42>
114 stos %eax,%es:(%rdi)
115 movl %cs,%eax #return segment
116 stos %ax,%es:(%rdi)
117 mov %edx,%eax #THUNK Flags
118 stos %ax,%es:(%rdi)
119 sgdt 0x58(%rsp) #save GDTR
120 mov 0x58(%rsp),%rax
121 stos %rax,%es:(%rdi)
122 mov %cr0,%rax #save CR0
123 mov %eax,%esi #esi <- CR0 to set
124 stos %eax,%es:(%rdi)
125 mov %cr4,%rax #save CR4
126 stos %eax,%es:(%rdi)
127 sidt 0x58(%rsp) #save IDTR
128 and $0x7ffffffe,%esi #clear PE & PG bits
129 mov %r10,%rdi #rdi <- 16-bit stack segment
130 shl $0x10,%r8
131 push %r8 #far jmp address
132 lea Label_16Bit,%eax
133 push %rax
134 movw $0x8,0x4(%rsp)
135 lgdt _16Gdtr #bugbug: may not match.
136 lret
137 Label_16Bit:
138 .byte 0x66
139 movl $0xc0000080,%ecx
140 mov %rsi,%cr0 #disable PE & PG
141 rdmsr
142 and $0xfe,%ah
143 wrmsr #clear LME bit
144 mov %cr4,%rax
145 and $0xcf,%al #clear PAE & PSE
146 mov %rax,%cr4
147 lret
148
149 Label:
150 xor %rax,%rax
151 movl %ss,%eax
152 shl $0x4,%eax
153 add %esp,%eax
154 mov %r15,%rsp
155 lidt 0x58(%rsp)
156 movl %r12d,%ds
157 movl %r13d,%es
158 movl %r14d,%ss
159 popq %gs
160 popq %fs
161 pop %r15
162 pop %r14
163 pop %r13
164 pop %r12
165 pop %rdi
166 pop %rsi
167 pop %rbx
168 pop %rbp
169 retq
170
171
172 .p2align 4
173
174 _Code16Addr:
175 ASM_PFX(RealMode):
176 movl %edi,%ss
177 mov %bx,%sp #set up 16-bit stack
178 .byte 0x2e
179 .byte 0x0f
180 .byte 0x01
181 .byte 0x1e
182 .word _16Idtr - _Code16Addr #lidt _16Idtr
183 .byte 0x66
184 .byte 0x61 #popad
185 .byte 0x1f #pop ds
186 .byte 0x07 #pop es
187 popq %fs
188 popq %gs
189 sub 64, %esp
190 .byte 0x66, 0x9d #popfd
191 add $0x4,%esp #skip high part of RFLAGS
192 .byte 0x67 #; test (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1
193 .byte 0xf7
194 .byte 0x44
195 .byte 0x24
196 .byte 0x4e
197 .byte 0x01
198 .byte 0x00
199 jz 1f
200 pushfq #pushf, actually, when it's INT#
201 1:
202 .byte 0x0e #push cs
203 .byte 0x68 #push /iw
204 .word FarCallRet - _Code16Addr
205 jz 2f
206 .byte 0x66
207 ljmp *70(%esp)
208 2:
209 .byte 0x66
210 ljmp *68(%esp)
211 FarCallRet:
212 add 64, %esp
213 .byte 0x66
214 push $0x00 #push a dword of zero
215 .byte 0x66
216 pushf #pushfd, actually
217 pushq %gs
218 pushq %fs
219 .byte 0x06 #push %es
220 .byte 0x1e #push %ds
221 .byte 0x66
222 .byte 0x60
223 cli
224 .byte 0x66 #sizeof (IA32_REGS) = 13 * 4 = 52
225 lgdt 64(%esp) #lgdt (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr
226 .byte 0x66
227 mov 76(%esp), %eax
228 mov %rax, %cr4
229 .byte 0x66
230 mov $0xc0000080, %ecx
231 rdmsr
232 orb $1, %ah
233 wrmsr
234 .byte 0x66
235 mov 72(%esp), %eax
236 mov %rax, %cr0 #restore CR0
237 .byte 0x66
238 ljmpl *52(%esp)
239
240 _16Idtr:
241 .word 0x3ff #FWORD (1 SHL 10) - 1
242 .byte 0x00