]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/X64/Thunk16.asm
1. Updated function headers in all assembly files.
[mirror_edk2.git] / MdePkg / Library / BaseLib / X64 / Thunk16.asm
1 ;------------------------------------------------------------------------------
2 ;
3 ; Copyright (c) 2006, Intel Corporation
4 ; All rights reserved. This program and the accompanying materials
5 ; are licensed and made available under the terms and conditions of the BSD License
6 ; which accompanies this distribution. The full text of the license may be found at
7 ; http://opensource.org/licenses/bsd-license.php
8 ;
9 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 ;
12 ; Module Name:
13 ;
14 ; Thunk.asm
15 ;
16 ; Abstract:
17 ;
18 ; Real mode thunk
19 ;
20 ;------------------------------------------------------------------------------
21
22 EXTERNDEF m16Start:BYTE
23 EXTERNDEF m16Size:WORD
24 EXTERNDEF mThunk16Attr:WORD
25 EXTERNDEF m16Gdt:WORD
26 EXTERNDEF m16GdtrBase:WORD
27 EXTERNDEF mTransition:WORD
28
29 IA32_REGS STRUC 4t
30 _EDI DD ?
31 _ESI DD ?
32 _EBP DD ?
33 _ESP DD ?
34 _EBX DD ?
35 _EDX DD ?
36 _ECX DD ?
37 _EAX DD ?
38 _DS DW ?
39 _ES DW ?
40 _FS DW ?
41 _GS DW ?
42 _EFLAGS DQ ?
43 _EIP DD ?
44 _CS DW ?
45 _SS DW ?
46 IA32_REGS ENDS
47
48 .const
49
50 m16Size DW InternalAsmThunk16 - m16Start
51 mThunk16Attr DW _ThunkAttr - m16Start
52 m16Gdt DW _NullSegDesc - m16Start
53 m16GdtrBase DW _16GdtrBase - m16Start
54 mTransition DW _EntryPoint - m16Start
55
56 .code
57
58 m16Start LABEL BYTE
59
60 SavedGdt LABEL FWORD
61 DW ?
62 DQ ?
63
64 ;------------------------------------------------------------------------------
65 ; _BackFromUserCode() takes control in real mode after 'retf' has been executed
66 ; by user code. It will be shadowed to somewhere in memory below 1MB.
67 ;------------------------------------------------------------------------------
68 _BackFromUserCode PROC
69 DB 16h ; push ss
70 DB 0eh ; push cs
71 DB 66h
72 call @Base ; push eip
73 @Base:
74 DB 66h
75 push 0 ; reserved high order 32 bits of EFlags
76 pushf ; pushfd actually
77 cli ; disable interrupts
78 push gs
79 push fs
80 DB 6 ; push es
81 DB 1eh ; push ds
82 DB 66h, 60h ; pushad
83 DB 66h, 0bah ; mov edx, imm32
84 _ThunkAttr DD ?
85 test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15
86 jz @1
87 mov eax, 15cd2401h ; mov ax, 2401h & int 15h
88 cli ; disable interrupts
89 jnc @2
90 @1:
91 test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL
92 jz @2
93 in al, 92h
94 or al, 2
95 out 92h, al ; deactivate A20M#
96 @2:
97 mov eax, ss
98 lea bp, [esp + sizeof (IA32_REGS)]
99 mov word ptr (IA32_REGS ptr [rsi - sizeof (IA32_REGS)])._ESP, bp
100 mov ebx, (IA32_REGS ptr [rsi - sizeof (IA32_REGS)])._EIP
101 shl ax, 4 ; shl eax, 4
102 add bp, ax ; add ebp, eax
103 DB 66h, 0b8h ; mov eax, imm32
104 SavedCr4 DD ?
105 mov cr4, rax
106 DB 66h, 2eh
107 lgdt fword ptr [rdi + (SavedGdt - @Base)]
108 DB 66h
109 mov ecx, 0c0000080h
110 rdmsr
111 or ah, 1
112 wrmsr
113 DB 66h, 0b8h ; mov eax, imm32
114 SavedCr0 DD ?
115 mov cr0, rax
116 DB 0b8h ; mov ax, imm16
117 SavedSs DW ?
118 mov ss, eax
119 DB 66h, 0bch ; mov esp, imm32
120 SavedEsp DD ?
121 DB 66h
122 retf ; return to protected mode
123 _BackFromUserCode ENDP
124
125 _EntryPoint DD _ToUserCode - m16Start
126 DW 8h
127 _16Gdtr LABEL FWORD
128 DW GdtEnd - _NullSegDesc - 1
129 _16GdtrBase DQ _NullSegDesc
130 _16Idtr FWORD (1 SHL 10) - 1
131
132 ;------------------------------------------------------------------------------
133 ; _ToUserCode() takes control in real mode before passing control to user code.
134 ; It will be shadowed to somewhere in memory below 1MB.
135 ;------------------------------------------------------------------------------
136 _ToUserCode PROC
137 mov edi, ss
138 mov ss, edx ; set new segment selectors
139 mov ds, edx
140 mov es, edx
141 mov fs, edx
142 mov gs, edx
143 DB 66h
144 mov ecx, 0c0000080h
145 mov cr0, rax ; real mode starts at next instruction
146 rdmsr
147 and ah, NOT 1
148 wrmsr
149 mov cr4, rbp
150 mov ss, esi ; set up 16-bit stack segment
151 xchg sp, bx ; set up 16-bit stack pointer
152 DB 66h
153 call @Base ; push eip
154 @Base:
155 pop bp ; ebp <- address of @Base
156 push [esp + sizeof (IA32_REGS) + 2]
157 lea eax, [rsi + (@RealMode - @Base)]
158 push rax
159 retf
160 @RealMode:
161 DB 2eh ; cs:
162 mov [rsi + (SavedSs - @Base)], edi
163 DB 2eh ; cs:
164 mov [rsi + (SavedEsp - @Base)], bx
165 DB 66h, 2eh ; CS and operand size override
166 lidt fword ptr [rsi + (_16Idtr - @Base)]
167 DB 66h, 61h ; popad
168 DB 1fh ; pop ds
169 DB 07h ; pop es
170 pop fs
171 pop gs
172 popf ; popfd
173 lea sp, [esp + 4] ; skip high order 32 bits of EFlags
174 DB 66h
175 retf ; transfer control to user code
176 _ToUserCode ENDP
177
178 _NullSegDesc DQ 0
179 _16CsDesc LABEL QWORD
180 DW -1
181 DW 0
182 DB 0
183 DB 9bh
184 DB 8fh ; 16-bit segment, 4GB limit
185 DB 0
186 _16DsDesc LABEL QWORD
187 DW -1
188 DW 0
189 DB 0
190 DB 93h
191 DB 8fh ; 16-bit segment, 4GB limit
192 DB 0
193 GdtEnd LABEL QWORD
194
195 ;------------------------------------------------------------------------------
196 ; IA32_REGISTER_SET *
197 ; EFIAPI
198 ; InternalAsmThunk16 (
199 ; IN IA32_REGISTER_SET *RegisterSet,
200 ; IN OUT VOID *Transition
201 ; );
202 ;------------------------------------------------------------------------------
203 InternalAsmThunk16 PROC USES rbp rbx rsi rdi
204 mov r10d, ds
205 mov r11d, es
206 push fs
207 push gs
208 mov rsi, rcx
209 movzx r8d, (IA32_REGS ptr [rsi])._SS
210 mov edi, (IA32_REGS ptr [rsi])._ESP
211 lea rdi, [edi - (sizeof (IA32_REGS) + 4)]
212 imul eax, r8d, 16 ; eax <- r8d(stack segment) * 16
213 mov ebx, edi ; ebx <- stack for 16-bit code
214 push sizeof (IA32_REGS) / 4
215 add edi, eax ; edi <- linear address of 16-bit stack
216 pop rcx
217 rep movsd ; copy RegSet
218 lea ecx, [rdx + (SavedCr4 - m16Start)]
219 mov eax, edx ; eax <- transition code address
220 and edx, 0fh
221 shl eax, 12
222 lea edx, [rdx + (_BackFromUserCode - m16Start)]
223 mov ax, dx
224 stosd ; [edi] <- return address of user code
225 sgdt fword ptr [rcx + (SavedGdt - SavedCr4)]
226 sidt fword ptr [rsp + 38h] ; save IDT stack in argument space
227 mov rax, cr0
228 mov [rcx + (SavedCr0 - SavedCr4)], eax
229 and eax, 7ffffffeh ; clear PE, PG bits
230 mov rbp, cr4
231 mov [rcx], ebp ; save CR4 in SavedCr4
232 and ebp, 300h ; clear all but PCE and OSFXSR bits
233 mov esi, r8d ; esi <- 16-bit stack segment
234 push 10h
235 pop rdx ; rdx <- selector for data segments
236 lgdt fword ptr [rcx + (_16Gdtr - SavedCr4)]
237 pushfq
238 call fword ptr [rcx + (_EntryPoint - SavedCr4)]
239 popfq
240 lidt fword ptr [rsp + 38h] ; restore protected mode IDTR
241 lea eax, [rbp - sizeof (IA32_REGS)]
242 pop gs
243 pop fs
244 mov es, r11d
245 mov ds, r10d
246 ret
247 InternalAsmThunk16 ENDP
248
249 END