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