Provide default value for PCD in platform if user does not specify anything for it.
[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
878ddf1f 29IA32_REGS STRUC 4t\r
30_EDI DD ?\r
31_ESI DD ?\r
32_EBP DD ?\r
33_ESP DD ?\r
34_EBX DD ?\r
35_EDX DD ?\r
36_ECX DD ?\r
37_EAX DD ?\r
38_DS DW ?\r
39_ES DW ?\r
40_FS DW ?\r
41_GS DW ?\r
97d92bda 42_EFLAGS DQ ?\r
878ddf1f 43_EIP DD ?\r
44_CS DW ?\r
45_SS DW ?\r
46IA32_REGS ENDS\r
47\r
97d92bda 48 .const\r
49\r
bbe4ba81 50m16Size DW InternalAsmThunk16 - m16Start\r
51mThunk16Attr DW _ThunkAttr - m16Start\r
f23d790a 52m16Gdt DW _NullSeg - m16Start\r
bbe4ba81 53m16GdtrBase DW _16GdtrBase - m16Start\r
54mTransition DW _EntryPoint - m16Start\r
97d92bda 55\r
56 .code\r
57\r
58m16Start LABEL BYTE\r
59\r
bbe4ba81 60SavedGdt LABEL FWORD\r
61 DW ?\r
62 DQ ?\r
97d92bda 63\r
3f566587 64;------------------------------------------------------------------------------\r
65; _BackFromUserCode() takes control in real mode after 'retf' has been executed\r
66; by user code. It will be shadowed to somewhere in memory below 1MB.\r
67;------------------------------------------------------------------------------\r
97d92bda 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
bbe4ba81 107 lgdt fword ptr [rdi + (SavedGdt - @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
bbe4ba81 125_EntryPoint DD _ToUserCode - m16Start\r
f23d790a 126 DW CODE16\r
bbe4ba81 127_16Gdtr LABEL FWORD\r
f23d790a 128 DW GDT_SIZE - 1\r
129_16GdtrBase DQ _NullSeg\r
bbe4ba81 130_16Idtr FWORD (1 SHL 10) - 1\r
97d92bda 131\r
3f566587 132;------------------------------------------------------------------------------\r
133; _ToUserCode() takes control in real mode before passing control to user code.\r
134; It will be shadowed to somewhere in memory below 1MB.\r
135;------------------------------------------------------------------------------\r
97d92bda 136_ToUserCode PROC\r
97d92bda 137 mov ss, edx ; set new segment selectors\r
138 mov ds, edx\r
139 mov es, edx\r
140 mov fs, edx\r
141 mov gs, edx\r
878ddf1f 142 DB 66h\r
97d92bda 143 mov ecx, 0c0000080h\r
144 mov cr0, rax ; real mode starts at next instruction\r
145 rdmsr\r
146 and ah, NOT 1\r
147 wrmsr\r
148 mov cr4, rbp\r
149 mov ss, esi ; set up 16-bit stack segment\r
150 xchg sp, bx ; set up 16-bit stack pointer\r
878ddf1f 151 DB 66h\r
97d92bda 152 call @Base ; push eip\r
153@Base:\r
bbe4ba81 154 pop bp ; ebp <- address of @Base\r
18c319ae 155 push [esp + sizeof (IA32_REGS) + 2]\r
bbe4ba81 156 lea eax, [rsi + (@RealMode - @Base)]\r
18c319ae 157 push rax\r
158 retf\r
159@RealMode:\r
f23d790a 160 DB 6ah, DATA32\r
97d92bda 161 DB 2eh ; cs:\r
f23d790a 162 pop [rsi + (SavedSs - @Base)]\r
97d92bda 163 DB 2eh ; cs:\r
bbe4ba81 164 mov [rsi + (SavedEsp - @Base)], bx\r
97d92bda 165 DB 66h, 2eh ; CS and operand size override\r
bbe4ba81 166 lidt fword ptr [rsi + (_16Idtr - @Base)]\r
97d92bda 167 DB 66h, 61h ; popad\r
168 DB 1fh ; pop ds\r
169 DB 07h ; pop es\r
170 pop fs\r
171 pop gs\r
172 popf ; popfd\r
173 lea sp, [esp + 4] ; skip high order 32 bits of EFlags\r
878ddf1f 174 DB 66h\r
97d92bda 175 retf ; transfer control to user code\r
176_ToUserCode ENDP\r
177\r
f23d790a 178CODE16 = _16Code - $\r
179DATA16 = _16Data - $\r
180DATA32 = _32Data - $\r
181\r
182_NullSeg DQ 0\r
183_16Code LABEL QWORD\r
184 DW -1\r
185 DW 0\r
186 DB 0\r
187 DB 9bh\r
188 DB 8fh ; 16-bit segment, 4GB limit\r
189 DB 0\r
190_16Data LABEL QWORD\r
191 DW -1\r
192 DW 0\r
193 DB 0\r
194 DB 93h\r
195 DB 8fh ; 16-bit segment, 4GB limit\r
196 DB 0\r
197_32Data LABEL QWORD\r
198 DW -1\r
199 DW 0\r
200 DB 0\r
201 DB 93h\r
202 DB 0cfh ; 16-bit segment, 4GB limit\r
203 DB 0\r
204\r
205GDT_SIZE = $ - _NullSeg\r
97d92bda 206\r
3f566587 207;------------------------------------------------------------------------------\r
208; IA32_REGISTER_SET *\r
209; EFIAPI\r
210; InternalAsmThunk16 (\r
211; IN IA32_REGISTER_SET *RegisterSet,\r
212; IN OUT VOID *Transition\r
213; );\r
214;------------------------------------------------------------------------------\r
97d92bda 215InternalAsmThunk16 PROC USES rbp rbx rsi rdi\r
216 mov r10d, ds\r
217 mov r11d, es\r
f23d790a 218 mov r9d, ss\r
97d92bda 219 push fs\r
220 push gs\r
221 mov rsi, rcx\r
222 movzx r8d, (IA32_REGS ptr [rsi])._SS\r
223 mov edi, (IA32_REGS ptr [rsi])._ESP\r
224 lea rdi, [edi - (sizeof (IA32_REGS) + 4)]\r
225 imul eax, r8d, 16 ; eax <- r8d(stack segment) * 16\r
bbe4ba81 226 mov ebx, edi ; ebx <- stack for 16-bit code\r
97d92bda 227 push sizeof (IA32_REGS) / 4\r
228 add edi, eax ; edi <- linear address of 16-bit stack\r
229 pop rcx\r
230 rep movsd ; copy RegSet\r
bbe4ba81 231 lea ecx, [rdx + (SavedCr4 - m16Start)]\r
97d92bda 232 mov eax, edx ; eax <- transition code address\r
233 and edx, 0fh\r
234 shl eax, 12\r
bbe4ba81 235 lea edx, [rdx + (_BackFromUserCode - m16Start)]\r
97d92bda 236 mov ax, dx\r
237 stosd ; [edi] <- return address of user code\r
bbe4ba81 238 sgdt fword ptr [rcx + (SavedGdt - SavedCr4)]\r
97d92bda 239 sidt fword ptr [rsp + 38h] ; save IDT stack in argument space\r
240 mov rax, cr0\r
bbe4ba81 241 mov [rcx + (SavedCr0 - SavedCr4)], eax\r
97d92bda 242 and eax, 7ffffffeh ; clear PE, PG bits\r
243 mov rbp, cr4\r
244 mov [rcx], ebp ; save CR4 in SavedCr4\r
245 and ebp, 300h ; clear all but PCE and OSFXSR bits\r
246 mov esi, r8d ; esi <- 16-bit stack segment\r
f23d790a 247 DB 6ah, DATA32 ; push DATA32\r
248 pop rdx ; rdx <- 32-bit data segment selector\r
bbe4ba81 249 lgdt fword ptr [rcx + (_16Gdtr - SavedCr4)]\r
f23d790a 250 mov ss, edx\r
18c319ae 251 pushfq\r
f23d790a 252 lea edx, [rdx + DATA16 - DATA32]\r
bbe4ba81 253 call fword ptr [rcx + (_EntryPoint - SavedCr4)]\r
18c319ae 254 popfq\r
97d92bda 255 lidt fword ptr [rsp + 38h] ; restore protected mode IDTR\r
256 lea eax, [rbp - sizeof (IA32_REGS)]\r
878ddf1f 257 pop gs\r
258 pop fs\r
f23d790a 259 mov ss, r9d\r
97d92bda 260 mov es, r11d\r
261 mov ds, r10d\r
878ddf1f 262 ret\r
263InternalAsmThunk16 ENDP\r
264\r
265 END\r