]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Thunk16/X64/Thunk16.asm
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Thunk16 / X64 / Thunk16.asm
CommitLineData
3eb9473e 1;*****************************************************************************\r
2;*\r
3;* Copyright (c) 2006, Intel Corporation \r
4;* All rights reserved. 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.asm\r
15;* \r
16;* Abstract:\r
17;* \r
18;* Real mode thunk\r
19;* \r
20;*****************************************************************************\r
21\r
22EXTERNDEF mCode16Size:QWORD\r
23\r
24 .const\r
25\r
26mCode16Size DQ _Code16End - _Code16Addr\r
27\r
28 .data\r
29\r
30NullSegSel DQ 0\r
31_16CsSegSel LABEL QWORD\r
32 DW -1\r
33 DW 0\r
34 DB 0\r
35 DB 9bh\r
36 DB 8fh ; 16-bit segment\r
37 DB 0\r
38_16DsSegSel LABEL QWORD\r
39 DW -1\r
40 DW 0\r
41 DB 0\r
42 DB 93h\r
43 DB 8fh ; 16-bit segment\r
44 DB 0\r
45\r
46_16Gdtr LABEL FWORD\r
47 DW $ - offset NullSegSel - 1\r
48 DQ offset NullSegSel\r
49\r
50 .code\r
51\r
52IA32_REGS STRUC 4t\r
53_EDI DD ?\r
54_ESI DD ?\r
55_EBP DD ?\r
56_ESP DD ?\r
57_EBX DD ?\r
58_EDX DD ?\r
59_ECX DD ?\r
60_EAX DD ?\r
61_DS DW ?\r
62_ES DW ?\r
63_FS DW ?\r
64_GS DW ?\r
65_RFLAGS DQ ?\r
66_EIP DD ?\r
67_CS DW ?\r
68_SS DW ?\r
69IA32_REGS ENDS\r
70\r
71_STK16 STRUC 1t\r
72RetEip DD ?\r
73RetCs DW ?\r
74ThunkFlags DW ?\r
75SavedGdtr FWORD ?\r
76Resvd1 DW ?\r
77SavedCr0 DD ?\r
78SavedCr4 DD ?\r
79_STK16 ENDS\r
80\r
81_Thunk16 PROC USES rbp rbx rsi rdi r12 r13 r14 r15\r
82\r
83 push fs\r
84 push gs\r
85\r
86 mov r12d, ds\r
87 mov r13d, es\r
88 mov r14d, ss\r
89 mov r15, rsp\r
90 mov rsi, rcx\r
91 movzx r10, (IA32_REGS ptr [rsi])._SS\r
92 xor rdi, rdi\r
93 mov edi, (IA32_REGS ptr [rsi])._ESP\r
94 add rdi, - sizeof (IA32_REGS) - sizeof (_STK16)\r
95 push rdi\r
96 imul rax, r10, 16\r
97 add rdi, rax\r
98 push sizeof (IA32_REGS) / 4\r
99 pop rcx\r
100 rep movsd\r
101 pop rbx ; rbx <- 16-bit stack offset\r
102 lea eax, @F ; return offset\r
103 stosd\r
104 mov eax, cs ; return segment\r
105 stosw\r
106 mov eax, edx ; THUNK Flags\r
107 stosw\r
108 sgdt fword ptr [rsp + 58h] ; save GDTR\r
109 mov rax, [rsp + 58h]\r
110 stosq\r
111 mov rax, cr0 ; save CR0\r
112 mov esi, eax ; esi <- CR0 to set\r
113 stosd\r
114 mov rax, cr4 ; save CR4\r
115 stosd\r
116 sidt fword ptr [rsp + 58h] ; save IDTR\r
117 and esi, 07ffffffeh ; clear PE & PG bits\r
118 mov rdi, r10 ; rdi <- 16-bit stack segment\r
119\r
120 shl r8, 16\r
121 push r8 ; far jmp address\r
122 lea eax, @16Bit\r
123 push rax\r
124 mov word ptr [rsp + 4], 8\r
125 lgdt _16Gdtr\r
126 retf\r
127@16Bit:\r
128 DB 66h\r
129 mov ecx, 0c0000080h\r
130 mov cr0, rsi ; disable PE & PG\r
131 rdmsr\r
132 and ah, NOT 1\r
133 wrmsr ; clear LME bit\r
134 mov rax, cr4\r
135 and al, NOT 30h ; clear PAE & PSE\r
136 mov cr4, rax\r
137 retf\r
138@@:\r
139 xor rax, rax\r
140 mov eax, ss\r
141 shl eax, 4\r
142 add eax, esp ; rax <- address of 16-bit stack\r
143 mov rsp, r15\r
144 lidt fword ptr [rsp + 58h] ; restore IDTR\r
145 mov ds, r12d\r
146 mov es, r13d\r
147 mov ss, r14d\r
148 pop gs\r
149 pop fs\r
150 ret\r
151_Thunk16 ENDP\r
152\r
153 ALIGN 10h\r
154\r
155_Code16Addr PROC\r
156_Code16Addr ENDP\r
157\r
158RealMode PROC\r
159 mov ss, edi\r
160 mov sp, bx ; set up 16-bit stack\r
161 DB 2eh, 0fh, 1, 1eh\r
162 DW _16Idtr - _Code16Addr ; lidt _16Idtr\r
163 DB 66h, 61h ; popad\r
164 DB 1fh ; pop ds\r
165 DB 7 ; pop es\r
166 pop fs\r
167 pop gs\r
168\r
169 add esp, 8 ; skip RFLAGS\r
170 DB 67h, 0f7h, 44h, 24h, 0eh, 1, 0 ; test [esp + 0eh], 1\r
171 jz @F\r
172 pushfq ; pushf, actually\r
173@@:\r
174 DB 0eh ; push cs\r
175 DB 68h ; push /iw\r
176 DW @FarCallRet - _Code16Addr\r
177 jz @F\r
178 DB 66h\r
179 jmp fword ptr [esp + 6]\r
180@@:\r
181 DB 66h\r
182 jmp fword ptr [esp + 4]\r
183@FarCallRet:\r
184 DB 66h\r
185 push 0 ; push a dword of zero\r
186 pushf ; pushfd, actually\r
187 push gs\r
188 push fs\r
189 DB 6 ; push es\r
190 DB 1eh ; push ds\r
191 DB 66h, 60h ; pushad\r
192 cli\r
193\r
194 DB 66h\r
195 lgdt (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedGdtr\r
196 DB 66h\r
197 mov eax, (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedCr4\r
198 mov cr4, rax\r
199 DB 66h\r
200 mov ecx, 0c0000080h\r
201 rdmsr\r
202 or ah, 1\r
203 wrmsr ; set LME\r
204 DB 66h\r
205 mov eax, (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedCr0\r
206 mov cr0, rax\r
207 DB 66h\r
208 jmp fword ptr (_STK16 ptr [esp + sizeof(IA32_REGS)]).RetEip\r
209\r
210RealMode ENDP\r
211\r
212_16Idtr FWORD (1 SHL 10) - 1\r
213\r
214_Code16End:\r
215\r
216 END\r