]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/Ia32/Thunk16.nasm
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ia32 / Thunk16.nasm
CommitLineData
6dab5c8a
JJ
1\r
2#include "BaseLibInternals.h"\r
3\r
4;------------------------------------------------------------------------------\r
5;\r
6; Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
9344f092 7; SPDX-License-Identifier: BSD-2-Clause-Patent\r
6dab5c8a
JJ
8;\r
9; Module Name:\r
10;\r
11; Thunk.asm\r
12;\r
13; Abstract:\r
14;\r
15; Real mode thunk\r
16;\r
17;------------------------------------------------------------------------------\r
18\r
19global ASM_PFX(m16Size)\r
20global ASM_PFX(mThunk16Attr)\r
21global ASM_PFX(m16Gdt)\r
22global ASM_PFX(m16GdtrBase)\r
23global ASM_PFX(mTransition)\r
24global ASM_PFX(m16Start)\r
25\r
26struc IA32_REGS\r
27\r
28 ._EDI: resd 1\r
29 ._ESI: resd 1\r
30 ._EBP: resd 1\r
31 ._ESP: resd 1\r
32 ._EBX: resd 1\r
33 ._EDX: resd 1\r
34 ._ECX: resd 1\r
35 ._EAX: resd 1\r
36 ._DS: resw 1\r
37 ._ES: resw 1\r
38 ._FS: resw 1\r
39 ._GS: resw 1\r
40 ._EFLAGS: resd 1\r
41 ._EIP: resd 1\r
42 ._CS: resw 1\r
43 ._SS: resw 1\r
44 .size:\r
45\r
46endstruc\r
47\r
48;; .const\r
49\r
50SECTION .data\r
51\r
52;\r
53; These are global constant to convey information to C code.\r
54;\r
15f8eef7 55ASM_PFX(m16Size) DW ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start)\r
7458df40 56ASM_PFX(mThunk16Attr) DW _BackFromUserCode.ThunkAttrEnd - 4 - ASM_PFX(m16Start)\r
6dab5c8a
JJ
57ASM_PFX(m16Gdt) DW _NullSegDesc - ASM_PFX(m16Start)\r
58ASM_PFX(m16GdtrBase) DW _16GdtrBase - ASM_PFX(m16Start)\r
59ASM_PFX(mTransition) DW _EntryPoint - ASM_PFX(m16Start)\r
60\r
61SECTION .text\r
62\r
63ASM_PFX(m16Start):\r
64\r
65SavedGdt:\r
66 dw 0\r
67 dd 0\r
68\r
69;------------------------------------------------------------------------------\r
70; _BackFromUserCode() takes control in real mode after 'retf' has been executed\r
71; by user code. It will be shadowed to somewhere in memory below 1MB.\r
72;------------------------------------------------------------------------------\r
73_BackFromUserCode:\r
74 ;\r
75 ; The order of saved registers on the stack matches the order they appears\r
76 ; in IA32_REGS structure. This facilitates wrapper function to extract them\r
77 ; into that structure.\r
78 ;\r
f6888eea 79BITS 16\r
6dab5c8a
JJ
80 push ss\r
81 push cs\r
eabcdf3a
JJ
82 ;\r
83 ; Note: We can't use o32 on the next instruction because of a bug\r
84 ; in NASM 2.09.04 through 2.10rc1.\r
85 ;\r
86 call dword .Base ; push eip\r
a8458d6c 87.Base:\r
f6888eea 88 pushfd\r
6dab5c8a
JJ
89 cli ; disable interrupts\r
90 push gs\r
91 push fs\r
92 push es\r
93 push ds\r
f6888eea 94 pushad\r
7458df40
JJ
95 mov edx, strict dword 0\r
96.ThunkAttrEnd:\r
6dab5c8a 97 test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15\r
a8458d6c 98 jz .1\r
f6888eea
JJ
99 mov ax, 2401h\r
100 int 15h\r
6dab5c8a 101 cli ; disable interrupts\r
a8458d6c
JJ
102 jnc .2\r
103.1:\r
6dab5c8a 104 test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL\r
a8458d6c 105 jz .2\r
6dab5c8a
JJ
106 in al, 92h\r
107 or al, 2\r
108 out 92h, al ; deactivate A20M#\r
a8458d6c 109.2:\r
f6888eea
JJ
110 xor eax, eax\r
111 mov ax, ss\r
112 lea ebp, [esp + IA32_REGS.size]\r
113 mov [bp - IA32_REGS.size + IA32_REGS._ESP], ebp\r
114 mov bx, [bp - IA32_REGS.size + IA32_REGS._EIP]\r
115 shl eax, 4 ; shl eax, 4\r
116 add ebp, eax ; add ebp, eax\r
7458df40
JJ
117 mov eax, strict dword 0\r
118.SavedCr4End:\r
6dab5c8a 119 mov cr4, eax\r
f6888eea 120o32 lgdt [cs:bx + (SavedGdt - .Base)]\r
7458df40
JJ
121 mov eax, strict dword 0\r
122.SavedCr0End:\r
6dab5c8a 123 mov cr0, eax\r
7458df40
JJ
124 mov ax, strict word 0\r
125.SavedSsEnd:\r
6dab5c8a 126 mov ss, eax\r
7458df40
JJ
127 mov esp, strict dword 0\r
128.SavedEspEnd:\r
f6888eea 129o32 retf ; return to protected mode\r
6dab5c8a
JJ
130\r
131_EntryPoint:\r
132 DD _ToUserCode - ASM_PFX(m16Start)\r
133 DW 8h\r
134_16Idtr:\r
135 DW (1 << 10) - 1\r
136 DD 0\r
137_16Gdtr:\r
138 DW GdtEnd - _NullSegDesc - 1\r
139_16GdtrBase:\r
03e9db15 140 DD 0\r
6dab5c8a
JJ
141\r
142;------------------------------------------------------------------------------\r
143; _ToUserCode() takes control in real mode before passing control to user code.\r
144; It will be shadowed to somewhere in memory below 1MB.\r
145;------------------------------------------------------------------------------\r
146_ToUserCode:\r
f6888eea
JJ
147BITS 16\r
148 mov dx, ss\r
149 mov ss, cx ; set new segment selectors\r
150 mov ds, cx\r
151 mov es, cx\r
152 mov fs, cx\r
153 mov gs, cx\r
6dab5c8a
JJ
154 mov cr0, eax ; real mode starts at next instruction\r
155 ; which (per SDM) *must* be a far JMP.\r
7458df40
JJ
156 jmp 0:strict word 0\r
157.RealAddrEnd:\r
6dab5c8a 158 mov cr4, ebp\r
f6888eea
JJ
159 mov ss, si ; set up 16-bit stack segment\r
160 xchg esp, ebx ; set up 16-bit stack pointer\r
161 mov bp, [esp + IA32_REGS.size]\r
7458df40
JJ
162 mov [cs:bp + (_BackFromUserCode.SavedSsEnd - 2 - _BackFromUserCode)], dx\r
163 mov [cs:bp + (_BackFromUserCode.SavedEspEnd - 4 - _BackFromUserCode)], ebx\r
f6888eea
JJ
164 lidt [cs:bp + (_16Idtr - _BackFromUserCode)]\r
165\r
166 popad\r
6dab5c8a
JJ
167 pop ds\r
168 pop es\r
169 pop fs\r
170 pop gs\r
f6888eea 171 popfd\r
6dab5c8a 172\r
f6888eea 173o32 retf ; transfer control to user code\r
6dab5c8a
JJ
174\r
175ALIGN 16\r
176_NullSegDesc DQ 0\r
177_16CsDesc:\r
178 DW -1\r
179 DW 0\r
180 DB 0\r
181 DB 9bh\r
182 DB 8fh ; 16-bit segment, 4GB limit\r
183 DB 0\r
184_16DsDesc:\r
185 DW -1\r
186 DW 0\r
187 DB 0\r
188 DB 93h\r
189 DB 8fh ; 16-bit segment, 4GB limit\r
190 DB 0\r
191GdtEnd:\r
192\r
193;------------------------------------------------------------------------------\r
194; IA32_REGISTER_SET *\r
195; EFIAPI\r
196; InternalAsmThunk16 (\r
197; IN IA32_REGISTER_SET *RegisterSet,\r
198; IN OUT VOID *Transition\r
199; );\r
200;------------------------------------------------------------------------------\r
201global ASM_PFX(InternalAsmThunk16)\r
202ASM_PFX(InternalAsmThunk16):\r
f6888eea 203BITS 32\r
6dab5c8a
JJ
204 push ebp\r
205 push ebx\r
206 push esi\r
207 push edi\r
208 push ds\r
209 push es\r
210 push fs\r
211 push gs\r
212 mov esi, [esp + 36] ; esi <- RegSet, the 1st parameter\r
213 movzx edx, word [esi + IA32_REGS._SS]\r
214 mov edi, [esi + IA32_REGS._ESP]\r
215 add edi, - (IA32_REGS.size + 4) ; reserve stack space\r
216 mov ebx, edi ; ebx <- stack offset\r
217 imul eax, edx, 16 ; eax <- edx * 16\r
218 push IA32_REGS.size / 4\r
219 add edi, eax ; edi <- linear address of 16-bit stack\r
220 pop ecx\r
221 rep movsd ; copy RegSet\r
222 mov eax, [esp + 40] ; eax <- address of transition code\r
223 mov esi, edx ; esi <- 16-bit stack segment\r
7458df40 224 lea edx, [eax + (_BackFromUserCode.SavedCr0End - ASM_PFX(m16Start))]\r
6dab5c8a
JJ
225 mov ecx, eax\r
226 and ecx, 0fh\r
227 shl eax, 12\r
228 lea ecx, [ecx + (_BackFromUserCode - ASM_PFX(m16Start))]\r
229 mov ax, cx\r
230 stosd ; [edi] <- return address of user code\r
7458df40
JJ
231 add eax, _ToUserCode.RealAddrEnd - _BackFromUserCode\r
232 mov [edx + (_ToUserCode.RealAddrEnd - 4 - _BackFromUserCode.SavedCr0End)], eax\r
233 sgdt [edx + (SavedGdt - _BackFromUserCode.SavedCr0End)]\r
6dab5c8a
JJ
234 sidt [esp + 36] ; save IDT stack in argument space\r
235 mov eax, cr0\r
7458df40 236 mov [edx - 4], eax ; save CR0 in _BackFromUserCode.SavedCr0End - 4\r
6dab5c8a
JJ
237 and eax, 7ffffffeh ; clear PE, PG bits\r
238 mov ebp, cr4\r
7458df40 239 mov [edx + (_BackFromUserCode.SavedCr4End - 4 - _BackFromUserCode.SavedCr0End)], ebp\r
6dab5c8a
JJ
240 and ebp, ~30h ; clear PAE, PSE bits\r
241 push 10h\r
242 pop ecx ; ecx <- selector for data segments\r
7458df40 243 lgdt [edx + (_16Gdtr - _BackFromUserCode.SavedCr0End)]\r
6dab5c8a 244 pushfd ; Save df/if indeed\r
7458df40 245 call dword far [edx + (_EntryPoint - _BackFromUserCode.SavedCr0End)]\r
6dab5c8a
JJ
246 popfd\r
247 lidt [esp + 36] ; restore protected mode IDTR\r
248 lea eax, [ebp - IA32_REGS.size] ; eax <- the address of IA32_REGS\r
249 pop gs\r
250 pop fs\r
251 pop es\r
252 pop ds\r
253 pop edi\r
254 pop esi\r
255 pop ebx\r
256 pop ebp\r
257 ret\r