]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/X64/Thunk16.asm
Fix EDKT138. And add active_platform file info for stand alone module build.
[mirror_edk2.git] / MdePkg / Library / BaseLib / X64 / Thunk16.asm
CommitLineData
878ddf1f 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
97d92bda 22EXTERNDEF m16Start:BYTE\r
23EXTERNDEF m16Size:WORD\r
24EXTERNDEF mThunk16Attr:WORD\r
25EXTERNDEF m16Gdt:WORD\r
26EXTERNDEF m16GdtrBase:WORD\r
27EXTERNDEF mTransition:WORD\r
878ddf1f 28\r
a661b687 29;THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 EQU 2\r
30;THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL EQU 4\r
23f52b03 31\r
878ddf1f 32IA32_REGS STRUC 4t\r
33_EDI DD ?\r
34_ESI DD ?\r
35_EBP DD ?\r
36_ESP DD ?\r
37_EBX DD ?\r
38_EDX DD ?\r
39_ECX DD ?\r
40_EAX DD ?\r
41_DS DW ?\r
42_ES DW ?\r
43_FS DW ?\r
44_GS DW ?\r
97d92bda 45_EFLAGS DQ ?\r
878ddf1f 46_EIP DD ?\r
47_CS DW ?\r
48_SS DW ?\r
49IA32_REGS ENDS\r
50\r
97d92bda 51 .const\r
52\r
53m16Size DW offset InternalAsmThunk16 - offset m16Start\r
54mThunk16Attr DW offset _ThunkAttr - offset m16Start\r
55m16Gdt DW offset _NullSegDesc - offset m16Start\r
56m16GdtrBase DW offset _16GdtrBase - offset m16Start\r
57mTransition DW offset _EntryPoint - offset m16Start\r
58\r
59 .code\r
60\r
61m16Start LABEL BYTE\r
62\r
63SavedGdt LABEL FWORD\r
64 DW ?\r
65 DQ ?\r
66\r
67_BackFromUserCode PROC\r
68 DB 16h ; push ss\r
69 DB 0eh ; push cs\r
878ddf1f 70 DB 66h\r
97d92bda 71 call @Base ; push eip\r
72@Base:\r
878ddf1f 73 DB 66h\r
97d92bda 74 push 0 ; reserved high order 32 bits of EFlags\r
878ddf1f 75 pushf ; pushfd actually\r
97d92bda 76 cli ; disable interrupts\r
878ddf1f 77 push gs\r
78 push fs\r
79 DB 6 ; push es\r
80 DB 1eh ; push ds\r
81 DB 66h, 60h ; pushad\r
97d92bda 82 DB 66h, 0bah ; mov edx, imm32\r
83_ThunkAttr DD ?\r
84 test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15\r
85 jz @1\r
86 mov eax, 15cd2401h ; mov ax, 2401h & int 15h\r
87 cli ; disable interrupts\r
88 jnc @2\r
89@1:\r
90 test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL\r
91 jz @2\r
92 in al, 92h\r
93 or al, 2\r
94 out 92h, al ; deactivate A20M#\r
95@2:\r
96 mov eax, ss\r
97 lea bp, [esp + sizeof (IA32_REGS)]\r
98 mov word ptr (IA32_REGS ptr [rsi - sizeof (IA32_REGS)])._ESP, bp\r
99 mov ebx, (IA32_REGS ptr [rsi - sizeof (IA32_REGS)])._EIP\r
100 shl ax, 4 ; shl eax, 4\r
101 add bp, ax ; add ebp, eax\r
102 DB 66h, 0b8h ; mov eax, imm32\r
103SavedCr4 DD ?\r
104 mov cr4, rax\r
105 DB 66h, 2eh\r
106 lgdt fword ptr [rdi + (offset SavedGdt - offset @Base)]\r
878ddf1f 107 DB 66h\r
108 mov ecx, 0c0000080h\r
109 rdmsr\r
97d92bda 110 or ah, 1\r
878ddf1f 111 wrmsr\r
97d92bda 112 DB 66h, 0b8h ; mov eax, imm32\r
113SavedCr0 DD ?\r
114 mov cr0, rax\r
115 DB 0b8h ; mov ax, imm16\r
116SavedSs DW ?\r
117 mov ss, eax\r
118 DB 66h, 0bch ; mov esp, imm32\r
119SavedEsp DD ?\r
878ddf1f 120 DB 66h\r
97d92bda 121 retf ; return to protected mode\r
122_BackFromUserCode ENDP\r
123\r
124_EntryPoint DD offset _ToUserCode - offset m16Start\r
125 DW 8h\r
126_16Gdtr LABEL FWORD\r
127 DW offset GdtEnd - offset _NullSegDesc - 1\r
128_16GdtrBase DQ offset _NullSegDesc\r
129_16Idtr FWORD (1 SHL 10) - 1\r
130\r
131_ToUserCode PROC\r
132 mov edi, ss\r
133 mov ss, edx ; set new segment selectors\r
134 mov ds, edx\r
135 mov es, edx\r
136 mov fs, edx\r
137 mov gs, edx\r
878ddf1f 138 DB 66h\r
97d92bda 139 mov ecx, 0c0000080h\r
140 mov cr0, rax ; real mode starts at next instruction\r
141 rdmsr\r
142 and ah, NOT 1\r
143 wrmsr\r
144 mov cr4, rbp\r
145 mov ss, esi ; set up 16-bit stack segment\r
146 xchg sp, bx ; set up 16-bit stack pointer\r
878ddf1f 147 DB 66h\r
97d92bda 148 call @Base ; push eip\r
149@Base:\r
150 pop bp ; ebp <- offset @Base\r
18c319ae 151 push [esp + sizeof (IA32_REGS) + 2]\r
152 lea eax, [rsi + (offset @RealMode - offset @Base)]\r
153 push rax\r
154 retf\r
155@RealMode:\r
97d92bda 156 DB 2eh ; cs:\r
157 mov [rsi + (offset SavedSs - offset @Base)], edi\r
158 DB 2eh ; cs:\r
159 mov [rsi + (offset SavedEsp - offset @Base)], bx\r
160 DB 66h, 2eh ; CS and operand size override\r
161 lidt fword ptr [rsi + (offset _16Idtr - offset @Base)]\r
162 DB 66h, 61h ; popad\r
163 DB 1fh ; pop ds\r
164 DB 07h ; pop es\r
165 pop fs\r
166 pop gs\r
167 popf ; popfd\r
168 lea sp, [esp + 4] ; skip high order 32 bits of EFlags\r
878ddf1f 169 DB 66h\r
97d92bda 170 retf ; transfer control to user code\r
171_ToUserCode ENDP\r
172\r
173_NullSegDesc DQ 0\r
174_16CsDesc LABEL QWORD\r
175 DW -1\r
176 DW 0\r
177 DB 0\r
178 DB 9bh\r
179 DB 8fh ; 16-bit segment, 4GB limit\r
180 DB 0\r
181_16DsDesc LABEL QWORD\r
182 DW -1\r
183 DW 0\r
184 DB 0\r
185 DB 93h\r
186 DB 8fh ; 16-bit segment, 4GB limit\r
187 DB 0\r
188GdtEnd LABEL QWORD\r
189\r
190;\r
191; @param RegSet Pointer to a IA32_DWORD_REGS structure\r
192; @param Transition Pointer to the transition code\r
193; @return The address of the 16-bit stack after returning from user code\r
194;\r
195InternalAsmThunk16 PROC USES rbp rbx rsi rdi\r
196 mov r10d, ds\r
197 mov r11d, es\r
198 push fs\r
199 push gs\r
200 mov rsi, rcx\r
201 movzx r8d, (IA32_REGS ptr [rsi])._SS\r
202 mov edi, (IA32_REGS ptr [rsi])._ESP\r
203 lea rdi, [edi - (sizeof (IA32_REGS) + 4)]\r
204 imul eax, r8d, 16 ; eax <- r8d(stack segment) * 16\r
205 mov ebx, edi ; ebx <- stack offset for 16-bit code\r
206 push sizeof (IA32_REGS) / 4\r
207 add edi, eax ; edi <- linear address of 16-bit stack\r
208 pop rcx\r
209 rep movsd ; copy RegSet\r
210 lea ecx, [rdx + (offset SavedCr4 - offset m16Start)]\r
211 mov eax, edx ; eax <- transition code address\r
212 and edx, 0fh\r
213 shl eax, 12\r
214 lea edx, [rdx + (offset _BackFromUserCode - offset m16Start)]\r
215 mov ax, dx\r
216 stosd ; [edi] <- return address of user code\r
217 sgdt fword ptr [rcx + (offset SavedGdt - offset SavedCr4)]\r
218 sidt fword ptr [rsp + 38h] ; save IDT stack in argument space\r
219 mov rax, cr0\r
220 mov [rcx + (offset SavedCr0 - offset SavedCr4)], eax\r
221 and eax, 7ffffffeh ; clear PE, PG bits\r
222 mov rbp, cr4\r
223 mov [rcx], ebp ; save CR4 in SavedCr4\r
224 and ebp, 300h ; clear all but PCE and OSFXSR bits\r
225 mov esi, r8d ; esi <- 16-bit stack segment\r
226 push 10h\r
227 pop rdx ; rdx <- selector for data segments\r
228 lgdt fword ptr [rcx + (offset _16Gdtr - offset SavedCr4)]\r
18c319ae 229 pushfq\r
97d92bda 230 call fword ptr [rcx + (offset _EntryPoint - offset SavedCr4)]\r
18c319ae 231 popfq\r
97d92bda 232 lidt fword ptr [rsp + 38h] ; restore protected mode IDTR\r
233 lea eax, [rbp - sizeof (IA32_REGS)]\r
878ddf1f 234 pop gs\r
235 pop fs\r
97d92bda 236 mov es, r11d\r
237 mov ds, r10d\r
878ddf1f 238 ret\r
239InternalAsmThunk16 ENDP\r
240\r
241 END\r