diff --git a/EdkModulePkg/Universal/Ebc/Dxe/x64/EbcLowLevel.S b/EdkModulePkg/Universal/Ebc/Dxe/x64/EbcLowLevel.S new file mode 100644 index 0000000000..61322a3264 --- /dev/null +++ b/EdkModulePkg/Universal/Ebc/Dxe/x64/EbcLowLevel.S @@ -0,0 +1,137 @@ +#**************************************************************************** +#* +#* Copyright (c) 2006, Intel Corporation +#* All rights reserved. This program and the accompanying materials +#* are licensed and made available under the terms and conditions of the BSD License +#* which accompanies this distribution. The full text of the license may be found at +#* http://opensource.org/licenses/bsd-license.php +#* +#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +#* +#**************************************************************************** +#**************************************************************************** +# REV 1.0 +#**************************************************************************** +# +# Rev Date Description +# --- -------- ------------------------------------------------------------ +# 1.0 05/09/12 Initial creation of file. +# +#**************************************************************************** + +#* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +# This code provides low level routines that support the Virtual Machine +# for option ROMs. +#* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +#--------------------------------------------------------------------------- +# Equate files needed. +#--------------------------------------------------------------------------- + +#--------------------------------------------------------------------------- +##GenericPostSegment SEGMENT USE16 +#--------------------------------------------------------------------------- + +#**************************************************************************** +# EbcLLCALLEX +# +# This function is called to execute an EBC CALLEX instruction. +# This instruction requires that we thunk out to external native +# code. For x64, we switch stacks, copy the arguments to the stack +# and jump to the specified function. +# On return, we restore the stack pointer to its original location. +# +# Destroys no working registers. +#**************************************************************************** +# VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr) +.global _EbcLLCALLEXNative; +_EbcLLCALLEXNative: + push %rbp + push %rbx + mov %rsp, %rbp + # Function prolog + + # Copy FuncAddr to a preserved register. + mov %rcx, %rbx + + # Set stack pointer to new value + mov %rdx, %rsp + + # Considering the worst case, load 4 potiential arguments + # into registers. + mov (%rsp), %rcx + mov 8(%rsp), %rdx + mov 10(%rsp), %r8 + mov 18(%rsp), %r9 + + # Now call the external routine + call *%rbx + + # Function epilog + mov %rbp, %rsp + pop %rbx + pop %rbp + ret + + +# UINTN EbcLLGetEbcEntryPoint(VOID); +# Routine Description: +# The VM thunk code stuffs an EBC entry point into a processor +# register. Since we can't use inline assembly to get it from +# the interpreter C code, stuff it into the return value +# register and return. +# +# Arguments: +# None. +# +# Returns: +# The contents of the register in which the entry point is passed. +# +.global _EbcLLGetEbcEntryPoint; +_EbcLLGetEbcEntryPoint: + ret + +#/*++ +# +#Routine Description: +# +# Return the caller's value of the stack pointer. +# +#Arguments: +# +# None. +# +#Returns: +# +# The current value of the stack pointer for the caller. We +# adjust it by 4 here because when they called us, the return address +# is put on the stack, thereby lowering it by 4 bytes. +# +#--*/ + +# UINTN EbcLLGetStackPointer() +.global _EbcLLGetStackPointer; +_EbcLLGetStackPointer: + mov %rsp, %rax + # Stack adjusted by this much when we were called, + # For this function, it's 4. + add $4, %rax + ret + +.global _EbcLLGetReturnValue; +_EbcLLGetReturnValue: +# UINT64 EbcLLGetReturnValue(VOID); +# Routine Description: +# When EBC calls native, on return the VM has to stuff the return +# value into a VM register. It's assumed here that the value is still +# in the register, so simply return and the caller should get the +# return result properly. +# +# Arguments: +# None. +# +# Returns: +# The unmodified value returned by the native code. +# + ret