2 ; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
\r
3 ; This program and the accompanying materials
\r
4 ; are licensed and made available under the terms and conditions of the BSD License
\r
5 ; which accompanies this distribution. The full text of the license may be found at
\r
6 ; http://opensource.org/licenses/bsd-license.php.
\r
8 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
9 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
18 ; This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then
\r
19 ; transit back to long mode.
\r
21 ;-------------------------------------------------------------------------------
\r
24 ;----------------------------------------------------------------------------
\r
25 ; Procedure: AsmExecute32BitCode
\r
32 ; AsmExecute32BitCode (
\r
33 ; IN UINT64 Function,
\r
36 ; IN IA32_DESCRIPTOR *InternalGdtr
\r
40 ; Description: A thunk function to execute 32-bit code in long mode.
\r
42 ;----------------------------------------------------------------------------
\r
43 global ASM_PFX(AsmExecute32BitCode)
\r
44 ASM_PFX(AsmExecute32BitCode):
\r
46 ; save IFLAG and disable it
\r
52 ; save orignal GDTR and CS
\r
65 ; Save general purpose register and rflag register
\r
80 ; Prepare the CS and return address for the transition from 32-bit to 64-bit mode
\r
82 mov rax, dword 0x10 ; load long mode selector
\r
84 mov r9, ReloadCS ;Assume the ReloadCS is under 4G
\r
88 ; Save parameters for 32-bit function call
\r
95 ; save the 32-bit function entry and the return address into stack which will be
\r
96 ; retrieve in compatibility mode.
\r
98 mov rax, ReturnBack ;Assume the ReloadCS is under 4G
\r
106 mov rax, dword 0x18
\r
109 ; Change to Compatible Segment
\r
111 mov rcx, dword 0x8 ; load compatible mode selector
\r
113 mov rdx, Compatible ; assume address < 4G
\r
119 ; reload DS/ES/SS to make sure they are correct referred to current GDT
\r
133 mov ecx, 0xC0000080
\r
138 ; Now we are in protected mode
\r
140 ; Call 32-bit function. Assume the function entry address and parameter value is less than 4G
\r
142 pop rax ; Here is the function entry
\r
144 ; Now the parameter is at the bottom of the stack, then call in to IA32 function.
\r
148 mov ebx, eax ; save return status
\r
149 pop rcx ; drop param1
\r
150 pop rcx ; drop param2
\r
166 ; Set EFER.LME to re-enable ia32-e
\r
168 mov ecx, 0xC0000080
\r
178 ; Now we are in compatible mode
\r
181 ; Reload cs register
\r
186 ; Now we're in Long Mode
\r
189 ; Restore C register and eax hold the return status from 32-bit function.
\r
190 ; Note: Do not touch rax from now which hold the return value from IA32 function
\r
192 mov eax, ebx ; put return status to EAX
\r
199 ; Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor.
\r
203 ; drop GDT descriptor in stack
\r
207 ; switch to orignal CS and GDTR
\r
210 shl r9, 32 ; rcx[32..47] <- Cs
\r
217 ; Reload original DS/ES/SS
\r