summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/EbcDxe/x64/EbcLowLevel.S
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Universal/EbcDxe/x64/EbcLowLevel.S')
-rw-r--r--MdeModulePkg/Universal/EbcDxe/x64/EbcLowLevel.S144
1 files changed, 144 insertions, 0 deletions
diff --git a/MdeModulePkg/Universal/EbcDxe/x64/EbcLowLevel.S b/MdeModulePkg/Universal/EbcDxe/x64/EbcLowLevel.S
new file mode 100644
index 0000000..5384625
--- /dev/null
+++ b/MdeModulePkg/Universal/EbcDxe/x64/EbcLowLevel.S
@@ -0,0 +1,144 @@
+#****************************************************************************
+#*
+#* 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.
+#****************************************************************************
+.global _CopyMem;
+
+# 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
+ sub %r8, %rdx
+ sub %rsp, %r8
+ mov %rsp, %rcx
+ sub %rsp, 0x20
+ call _CopyMem
+ add %rsp, 0x20
+
+ # 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