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