Updated BaseLib for THUNK functions and some CPU functions
[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 THUNK_ATTRIBUTE_BIG_REAL_MODE EQU 1
30 THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 EQU 2
31 THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL EQU 4
32
33 IA32_REGS STRUC 4t
34 _EDI DD ?
35 _ESI DD ?
36 _EBP DD ?
37 _ESP DD ?
38 _EBX DD ?
39 _EDX DD ?
40 _ECX DD ?
41 _EAX DD ?
42 _DS DW ?
43 _ES DW ?
44 _FS DW ?
45 _GS DW ?
46 _EFLAGS DQ ?
47 _EIP DD ?
48 _CS DW ?
49 _SS DW ?
50 IA32_REGS ENDS
51
52 .const
53
54 m16Size DW offset InternalAsmThunk16 - offset m16Start
55 mThunk16Attr DW offset _ThunkAttr - offset m16Start
56 m16Gdt DW offset _NullSegDesc - offset m16Start
57 m16GdtrBase DW offset _16GdtrBase - offset m16Start
58 mTransition DW offset _EntryPoint - offset m16Start
59
60 .code
61
62 m16Start LABEL BYTE
63
64 SavedGdt LABEL FWORD
65 DW ?
66 DQ ?
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 + (offset SavedGdt - offset @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 offset _ToUserCode - offset m16Start
126 DW 8h
127 _16Gdtr LABEL FWORD
128 DW offset GdtEnd - offset _NullSegDesc - 1
129 _16GdtrBase DQ offset _NullSegDesc
130 _16Idtr FWORD (1 SHL 10) - 1
131
132 _ToUserCode PROC
133 mov edi, ss
134 mov ss, edx ; set new segment selectors
135 mov ds, edx
136 mov es, edx
137 mov fs, edx
138 mov gs, edx
139 DB 66h
140 mov ecx, 0c0000080h
141 mov cr0, rax ; real mode starts at next instruction
142 rdmsr
143 and ah, NOT 1
144 wrmsr
145 mov cr4, rbp
146 mov ss, esi ; set up 16-bit stack segment
147 xchg sp, bx ; set up 16-bit stack pointer
148 DB 66h
149 call @Base ; push eip
150 @Base:
151 pop bp ; ebp <- offset @Base
152 DB 2eh ; cs:
153 mov [rsi + (offset SavedSs - offset @Base)], edi
154 DB 2eh ; cs:
155 mov [rsi + (offset SavedEsp - offset @Base)], bx
156 DB 66h, 2eh ; CS and operand size override
157 lidt fword ptr [rsi + (offset _16Idtr - offset @Base)]
158 DB 66h, 61h ; popad
159 DB 1fh ; pop ds
160 DB 07h ; pop es
161 pop fs
162 pop gs
163 popf ; popfd
164 lea sp, [esp + 4] ; skip high order 32 bits of EFlags
165 DB 66h
166 retf ; transfer control to user code
167 _ToUserCode ENDP
168
169 _NullSegDesc DQ 0
170 _16CsDesc LABEL QWORD
171 DW -1
172 DW 0
173 DB 0
174 DB 9bh
175 DB 8fh ; 16-bit segment, 4GB limit
176 DB 0
177 _16DsDesc LABEL QWORD
178 DW -1
179 DW 0
180 DB 0
181 DB 93h
182 DB 8fh ; 16-bit segment, 4GB limit
183 DB 0
184 GdtEnd LABEL QWORD
185
186 ;
187 ; @param RegSet Pointer to a IA32_DWORD_REGS structure
188 ; @param Transition Pointer to the transition code
189 ; @return The address of the 16-bit stack after returning from user code
190 ;
191 InternalAsmThunk16 PROC USES rbp rbx rsi rdi
192 mov r10d, ds
193 mov r11d, es
194 push fs
195 push gs
196 mov rsi, rcx
197 movzx r8d, (IA32_REGS ptr [rsi])._SS
198 mov edi, (IA32_REGS ptr [rsi])._ESP
199 lea rdi, [edi - (sizeof (IA32_REGS) + 4)]
200 imul eax, r8d, 16 ; eax <- r8d(stack segment) * 16
201 mov ebx, edi ; ebx <- stack offset for 16-bit code
202 push sizeof (IA32_REGS) / 4
203 add edi, eax ; edi <- linear address of 16-bit stack
204 pop rcx
205 rep movsd ; copy RegSet
206 lea ecx, [rdx + (offset SavedCr4 - offset m16Start)]
207 mov eax, edx ; eax <- transition code address
208 and edx, 0fh
209 shl eax, 12
210 lea edx, [rdx + (offset _BackFromUserCode - offset m16Start)]
211 mov ax, dx
212 stosd ; [edi] <- return address of user code
213 sgdt fword ptr [rcx + (offset SavedGdt - offset SavedCr4)]
214 sidt fword ptr [rsp + 38h] ; save IDT stack in argument space
215 mov rax, cr0
216 mov [rcx + (offset SavedCr0 - offset SavedCr4)], eax
217 and eax, 7ffffffeh ; clear PE, PG bits
218 mov rbp, cr4
219 mov [rcx], ebp ; save CR4 in SavedCr4
220 and ebp, 300h ; clear all but PCE and OSFXSR bits
221 mov esi, r8d ; esi <- 16-bit stack segment
222 push 10h
223 pop rdx ; rdx <- selector for data segments
224 lgdt fword ptr [rcx + (offset _16Gdtr - offset SavedCr4)]
225 call fword ptr [rcx + (offset _EntryPoint - offset SavedCr4)]
226 lidt fword ptr [rsp + 38h] ; restore protected mode IDTR
227 lea eax, [rbp - sizeof (IA32_REGS)]
228 pop gs
229 pop fs
230 mov es, r11d
231 mov ds, r10d
232 ret
233 InternalAsmThunk16 ENDP
234
235 END