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