2 ; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
3 ; SPDX-License-Identifier: BSD-2-Clause-Patent
12 ; This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then
13 ; transit back to long mode.
15 ;-------------------------------------------------------------------------------
17 ;----------------------------------------------------------------------------
18 ; Procedure: AsmExecute32BitCode
25 ; AsmExecute32BitCode (
29 ; IN IA32_DESCRIPTOR *InternalGdtr
33 ; Description: A thunk function to execute 32-bit code in long mode.
35 ;----------------------------------------------------------------------------
36 AsmExecute32BitCode PROC
38 ; save IFLAG and disable it
44 ; save orignal GDTR and CS
57 ; Save general purpose register and rflag register
72 ; Prepare the CS and return address for the transition from 32-bit to 64-bit mode
74 mov rax, 10h ; load long mode selector
76 mov r9, OFFSET ReloadCS ;Assume the ReloadCS is under 4G
80 ; Save parameters for 32-bit function call
87 ; save the 32-bit function entry and the return address into stack which will be
88 ; retrieve in compatibility mode.
90 mov rax, OFFSET ReturnBack ;Assume the ReloadCS is under 4G
101 ; Change to Compatible Segment
103 mov rcx, 08h ; load compatible mode selector
105 mov rdx, OFFSET Compatible ; assume address < 4G
111 ; reload DS/ES/SS to make sure they are correct referred to current GDT
130 ; Now we are in protected mode
132 ; Call 32-bit function. Assume the function entry address and parameter value is less than 4G
134 pop rax ; Here is the function entry
136 ; Now the parameter is at the bottom of the stack, then call in to IA32 function.
140 mov ebx, eax ; save return status
141 pop rcx ; drop param1
142 pop rcx ; drop param2
158 ; Set EFER.LME to re-enable ia32-e
170 ; Now we are in compatible mode
178 ; Now we're in Long Mode
181 ; Restore C register and eax hold the return status from 32-bit function.
182 ; Note: Do not touch rax from now which hold the return value from IA32 function
184 mov eax, ebx ; put return status to EAX
191 ; Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor.
195 ; drop GDT descriptor in stack
199 ; switch to orignal CS and GDTR
202 shl r9, 32 ; rcx[32..47] <- Cs
209 ; Reload original DS/ES/SS
222 AsmExecute32BitCode ENDP