1 ;*****************************************************************************
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
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.
20 ;*****************************************************************************
24 EXTERNDEF C mCode16Size:DWORD
26 CONST SEGMENT FLAT "DATA" READONLY
28 mCode16Size DD _TEXT16SIZE
32 _DATA SEGMENT FLAT "DATA"
35 _16BitCsSel LABEL QWORD
40 DB 8fh ; 16-bit segment
42 _16BitSsSel LABEL QWORD
47 DB 8fh ; 16-bit segment
51 DW $ - offset NullSegSel - 1
56 _TEXT SEGMENT FLAT "CODE" PARA
58 STACK_PARAM_SIZE EQU 16
92 __Thunk16 PROC USES ebp ebx esi edi ds es fs gs
93 ASSUME esi:PTR IA32_REGS
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
103 rep movsd ; copy context to 16-bit stack
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
109 pop ebx ; ebx <- 16-bit stack offset
110 mov eax, offset @F ; return offset
112 mov eax, cs ; return segment
114 mov eax, [esp + 40] ; THUNK flags
118 mov eax, ss ; save ss
120 sgdt fword ptr [edi] ; save GDTR
121 sidt fword ptr [esp + 36] ; save IDTR
123 mov [edi + 6], esi ; save CR0
124 and esi, NOT 80000001h ; esi <- CR0 to set
126 mov [edi + 10], eax ; save CR4
127 and al, NOT 30h ; clear PAE & PSE
128 mov edi, edx ; edi <- 16-bit stack segment
133 mov dx, _16BitSsSel - NullSegSel
134 lgdt _16Gdtr ; load 16-bit GDTR
137 DW _16BitCsSel - NullSegSel ; jmp far 8:@16Bit
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]
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
154 _TEXT16 SEGMENT USE16 "CODE" PARA
160 mov ss, di ; set up stack
162 lidt fword ptr cs:[_16Idtr - _Code16Addr]
168 sub esp, (sizeof(IA32_REGS) - 12) + STACK_PARAM_SIZE + 4
170 test (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1
172 pushf ; push Flags when it's INT#
175 ; push @FarCallRet - _Code16Addr
177 DW @FarCallRet - _Code16Addr
179 jmp fword ptr [esp + 6 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
181 jmp fword ptr [esp + 4 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
183 add esp, (sizeof(IA32_REGS) - 12) + STACK_PARAM_SIZE + 4
192 lgdt (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr
193 mov eax, (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedCr4
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
200 _16Idtr FWORD (1 SHL 10) - 1
204 _TEXT16SIZE = _TEXT16END - _Code16Addr