]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Thunk16/X64/Thunk16.S
Add Acpi System Description Table protocol from PI 1.2 specification.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Thunk16 / X64 / Thunk16.S
CommitLineData
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
30mCode16Size: .long _Code16End - _Code16Addr
31
32
33NullSegSel: .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
83ASM_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
134Label_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
146Label:
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:
172ASM_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
1961:
197 .byte 0x0e #push cs
198 .byte 0x68 #push /iw
199 .word FarCallRet - _Code16Addr
200 jz 2f
201 .byte 0x66
202 ljmp *6(%esp)
2032:
204 .byte 0x66
205 ljmp *4(%esp)
206FarCallRet:
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