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