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