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 ;*****************************************************************************
22 EXTERNDEF mCode16Size:QWORD
26 mCode16Size DQ _Code16End - _Code16Addr
31 _16CsSegSel LABEL QWORD
36 DB 8fh ; 16-bit segment
38 _16DsSegSel LABEL QWORD
43 DB 8fh ; 16-bit segment
47 DW $ - offset NullSegSel - 1
52 STACK_PARAM_SIZE EQU 16
83 _Thunk16 PROC USES rbp rbx rsi rdi r12 r13 r14 r15
93 movzx r10, (IA32_REGS ptr [rsi])._SS
95 mov edi, (IA32_REGS ptr [rsi])._ESP
96 add rdi, - sizeof (IA32_REGS) - sizeof (_STK16)
100 push sizeof (IA32_REGS) / 4
104 ; copy eflags to stack frame
105 mov rax, (IA32_REGS ptr [rsi - sizeof(IA32_REGS)])._RFLAGS
106 mov [rdi - sizeof(IA32_REGS) - STACK_PARAM_SIZE - 8], rax
108 pop rbx ; rbx <- 16-bit stack offset
109 lea eax, @F ; return offset
111 mov eax, cs ; return segment
113 mov eax, edx ; THUNK Flags
115 sgdt fword ptr [rsp + 58h] ; save GDTR
118 mov rax, cr0 ; save CR0
119 mov esi, eax ; esi <- CR0 to set
121 mov rax, cr4 ; save CR4
123 sidt fword ptr [rsp + 58h] ; save IDTR
124 and esi, 07ffffffeh ; clear PE & PG bits
125 mov rdi, r10 ; rdi <- 16-bit stack segment
128 push r8 ; far jmp address
131 mov word ptr [rsp + 4], 8
137 mov cr0, rsi ; disable PE & PG
140 wrmsr ; clear LME bit
142 and al, NOT 30h ; clear PAE & PSE
149 add eax, esp ; rax <- address of 16-bit stack
151 lidt fword ptr [rsp + 58h] ; restore IDTR
167 mov sp, bx ; set up 16-bit stack
169 DW _16Idtr - _Code16Addr ; lidt _16Idtr
175 sub esp, (sizeof(IA32_REGS) - 16) + STACK_PARAM_SIZE + 8
178 add esp, 4 ; skip high part of RFLAGS
179 DB 67h, 0f7h, 44h, 24h ; test (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1
180 DB (STACK_PARAM_SIZE + sizeof(IA32_REGS) + 6)
183 pushfq ; pushf, actually, when it's INT#
187 DW @FarCallRet - _Code16Addr
190 jmp fword ptr [esp + 6 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
193 jmp fword ptr [esp + 4 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
195 add esp, (sizeof(IA32_REGS) - 16) + STACK_PARAM_SIZE + 8
197 push 0 ; push a dword of zero
198 pushf ; pushfd, actually
207 lgdt (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedGdtr
209 mov eax, (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedCr4
217 mov eax, (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedCr0
220 jmp fword ptr (_STK16 ptr [esp + sizeof(IA32_REGS)]).RetEip
224 _16Idtr FWORD (1 SHL 10) - 1