]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Thunk16/Ia32/Thunk16.asm
0a796ed236b8cdc724170e8374fe753415492836
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Thunk16 / Ia32 / Thunk16.asm
1 ;*****************************************************************************
2 ;*
3 ;* Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4 ;* 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 .686p
23
24 EXTERNDEF C mCode16Size:DWORD
25
26 CONST SEGMENT FLAT "DATA" READONLY
27
28 mCode16Size DD _TEXT16SIZE
29
30 CONST ENDS
31
32 _DATA SEGMENT FLAT "DATA"
33
34 NullSegSel DQ 0
35 _16BitCsSel LABEL QWORD
36 DW -1
37 DW 0
38 DB 0
39 DB 9bh
40 DB 8fh ; 16-bit segment
41 DB 0
42 _16BitSsSel LABEL QWORD
43 DW -1
44 DW 0
45 DB 0
46 DB 93h
47 DB 8fh ; 16-bit segment
48 DB 0
49
50 _16Gdtr LABEL FWORD
51 DW $ - offset NullSegSel - 1
52 DD offset NullSegSel
53
54 _DATA ENDS
55
56 _TEXT SEGMENT FLAT "CODE" PARA
57
58 STACK_PARAM_SIZE EQU 16
59
60 IA32_REGS STRUC 4t
61 _EDI DD ?
62 _ESI DD ?
63 _EBP DD ?
64 _ESP DD ?
65 _EBX DD ?
66 _EDX DD ?
67 _ECX DD ?
68 _EAX DD ?
69 _DS DW ?
70 _ES DW ?
71 _FS DW ?
72 _GS DW ?
73 _EFLAGS DD ?
74 _EIP DD ?
75 _CS DW ?
76 _SS DW ?
77 IA32_REGS ENDS
78
79 _STK16 STRUC 1t
80 RetEip DD ?
81 RetCs DW ?
82 ThunkFlags DW ?
83 SavedEsp DD ?
84 SavedSs DW ?
85 SavedGdtr FWORD ?
86 SavedCr0 DD ?
87 SavedCr4 DD ?
88 _STK16 ENDS
89
90 ASSUME ds:_DATA
91
92 __Thunk16 PROC USES ebp ebx esi edi ds es fs gs
93 ASSUME esi:PTR IA32_REGS
94 mov esi, [esp + 36]
95 movzx edx, [esi]._SS
96 mov edi, [esi]._ESP
97 add edi, - sizeof (_STK16) - sizeof (IA32_REGS)
98 push edi ; save stack offset
99 imul eax, edx, 16 ; eax <- edx*16
100 add edi, eax ; edi <- linear address of 16-bit stack
101 push sizeof (IA32_REGS) / 4
102 pop ecx
103 rep movsd ; copy context to 16-bit stack
104
105 ; copy eflags to stack frame
106 mov eax, [esi - sizeof(IA32_REGS)]._EFLAGS
107 mov [edi - sizeof(IA32_REGS) - STACK_PARAM_SIZE - 4], eax
108
109 pop ebx ; ebx <- 16-bit stack offset
110 mov eax, offset @F ; return offset
111 stosd
112 mov eax, cs ; return segment
113 stosw
114 mov eax, [esp + 40] ; THUNK flags
115 stosw
116 mov eax, esp
117 stosd ; save esp
118 mov eax, ss ; save ss
119 stosw
120 sgdt fword ptr [edi] ; save GDTR
121 sidt fword ptr [esp + 36] ; save IDTR
122 mov esi, cr0
123 mov [edi + 6], esi ; save CR0
124 and esi, NOT 80000001h ; esi <- CR0 to set
125 mov eax, cr4
126 mov [edi + 10], eax ; save CR4
127 and al, NOT 30h ; clear PAE & PSE
128 mov edi, edx ; edi <- 16-bit stack segment
129 mov edx, [esp + 44]
130 shl edx, 16
131 push edx
132 pop edx
133 mov dx, _16BitSsSel - NullSegSel
134 lgdt _16Gdtr ; load 16-bit GDTR
135 DB 0eah
136 DD offset @16Bit
137 DW _16BitCsSel - NullSegSel ; jmp far 8:@16Bit
138 @16Bit:
139 mov ss, dx
140 mov cr0, esi ; disable protected mode
141 mov cr4, eax ; disable PAE & PSE
142 db 67h, 0FFh, 06Ch, 024h, 0FCh ; jmp dword ptr [esp-4]
143 @@:
144 xor eax, eax
145 mov ax, ss
146 shl eax, 4
147 add eax, esp ; eax <- address of 16-bit stack
148 lss esp, fword ptr (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedEsp
149 lidt fword ptr [esp + 36] ; restore IDTR
150 ret
151 __Thunk16 ENDP
152
153 _TEXT ENDS
154
155 _TEXT16 SEGMENT USE16 "CODE" PARA
156
157 _Code16Addr PROC C
158 _Code16Addr ENDP
159
160 RealMode PROC
161 mov ss, di ; set up stack
162 mov esp, ebx
163 lidt fword ptr cs:[_16Idtr - _Code16Addr]
164 popad
165 pop ds
166 pop es
167 pop fs
168 pop gs
169 sub esp, (sizeof(IA32_REGS) - 12) + STACK_PARAM_SIZE + 4
170 popfd
171 test (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1
172 jz @F
173 pushf ; push Flags when it's INT#
174 @@:
175 push cs
176 ; push @FarCallRet - _Code16Addr
177 DB 68h ; push /iw
178 DW @FarCallRet - _Code16Addr
179 jz @F
180 jmp fword ptr [esp + 6 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
181 @@:
182 jmp fword ptr [esp + 4 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
183 @FarCallRet:
184 add esp, (sizeof(IA32_REGS) - 12) + STACK_PARAM_SIZE + 4
185 pushfd
186 push gs
187 push fs
188 push es
189 push ds
190 pushad
191 cli
192 DB 66h
193 lgdt (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr
194 mov eax, (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedCr4
195 mov cr4, eax
196 mov eax, (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedCr0
197 mov cr0, eax ; restore CR0
198 jmp fword ptr (_STK16 ptr [esp + sizeof (IA32_REGS)]).RetEip
199 RealMode ENDP
200
201 _16Idtr FWORD (1 SHL 10) - 1
202
203 _TEXT16END:
204
205 _TEXT16SIZE = _TEXT16END - _Code16Addr
206
207 _TEXT16 ENDS
208
209 END