]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Thunk16/Ia32/Thunk16.asm
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Thunk16 / Ia32 / Thunk16.asm
1 ;*****************************************************************************
2 ;*
3 ;* Copyright (c) 2006 - 2010, 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 mov eax, ss
145 shl eax, 4
146 add eax, esp ; eax <- address of 16-bit stack
147 lss esp, fword ptr (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedEsp
148 lidt fword ptr [esp + 36] ; restore IDTR
149 ret
150 __Thunk16 ENDP
151
152 _TEXT ENDS
153
154 _TEXT16 SEGMENT USE16 "CODE" PARA
155
156 _Code16Addr PROC C
157 _Code16Addr ENDP
158
159 RealMode PROC
160 mov ss, di ; set up stack
161 mov esp, ebx
162 lidt fword ptr cs:[_16Idtr - _Code16Addr]
163 popad
164 pop ds
165 pop es
166 pop fs
167 pop gs
168 sub esp, (sizeof(IA32_REGS) - 12) + STACK_PARAM_SIZE + 4
169 popfd
170 test (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1
171 jz @F
172 pushf ; push Flags when it's INT#
173 @@:
174 push cs
175 ; push @FarCallRet - _Code16Addr
176 DB 68h ; push /iw
177 DW @FarCallRet - _Code16Addr
178 jz @F
179 jmp fword ptr [esp + 6 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
180 @@:
181 jmp fword ptr [esp + 4 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
182 @FarCallRet:
183 add esp, (sizeof(IA32_REGS) - 12) + STACK_PARAM_SIZE + 4
184 pushfd
185 push gs
186 push fs
187 push es
188 push ds
189 pushad
190 cli
191 DB 66h
192 lgdt (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr
193 mov eax, (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedCr4
194 mov cr4, eax
195 mov eax, (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedCr0
196 mov cr0, eax ; restore CR0
197 jmp fword ptr (_STK16 ptr [esp + sizeof (IA32_REGS)]).RetEip
198 RealMode ENDP
199
200 _16Idtr FWORD (1 SHL 10) - 1
201
202 _TEXT16END:
203
204 _TEXT16SIZE = _TEXT16END - _Code16Addr
205
206 _TEXT16 ENDS
207
208 END