]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/EbcDxe/x64/EbcLowLevel.S
Update to fix minor coding style issues.
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / x64 / EbcLowLevel.S
CommitLineData
7b414b4e 1##/**@file\r
2# This code provides low level routines that support the Virtual Machine\r
3# for option ROMs.\r
53c71d09 4#\r
7b414b4e 5# Copyright (c) 2007 - 2008, Intel Corporation\r
6# All rights reserved. This program and the accompanying materials\r
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
53c71d09 10#\r
7b414b4e 11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14#**/\r
53c71d09 15\r
16#---------------------------------------------------------------------------\r
17# Equate files needed.\r
18#---------------------------------------------------------------------------\r
19\r
20#---------------------------------------------------------------------------\r
21##GenericPostSegment SEGMENT USE16\r
22#---------------------------------------------------------------------------\r
23\r
24#****************************************************************************\r
25# EbcLLCALLEX\r
26#\r
7b414b4e 27# This function is called to execute an EBC CALLEX instruction.\r
53c71d09 28# This instruction requires that we thunk out to external native\r
29# code. For x64, we switch stacks, copy the arguments to the stack\r
7b414b4e 30# and jump to the specified function.\r
53c71d09 31# On return, we restore the stack pointer to its original location.\r
32#\r
33# Destroys no working registers.\r
34#****************************************************************************\r
35.global _CopyMem;\r
36\r
37# VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)\r
38.global _EbcLLCALLEXNative;\r
39_EbcLLCALLEXNative:\r
40 push %rbp\r
41 push %rbx\r
42 mov %rsp, %rbp\r
43 # Function prolog\r
44\r
45 # Copy FuncAddr to a preserved register.\r
46 mov %rcx, %rbx\r
47\r
48 # Set stack pointer to new value\r
49 sub %r8, %rdx\r
50 sub %rsp, %r8\r
51 mov %rsp, %rcx\r
52 sub %rsp, 0x20\r
7b414b4e 53 call _CopyMem\r
53c71d09 54 add %rsp, 0x20\r
55\r
56 # Considering the worst case, load 4 potiential arguments\r
57 # into registers.\r
58 mov (%rsp), %rcx\r
59 mov 8(%rsp), %rdx\r
60 mov 10(%rsp), %r8\r
61 mov 18(%rsp), %r9\r
62\r
63 # Now call the external routine\r
64 call *%rbx\r
65\r
66 # Function epilog\r
67 mov %rbp, %rsp\r
68 pop %rbx\r
69 pop %rbp\r
70 ret\r
71\r
72\r
73# UINTN EbcLLGetEbcEntryPoint(VOID);\r
74# Routine Description:\r
75# The VM thunk code stuffs an EBC entry point into a processor\r
76# register. Since we can't use inline assembly to get it from\r
7b414b4e 77# the interpreter C code, stuff it into the return value\r
53c71d09 78# register and return.\r
79#\r
80# Arguments:\r
81# None.\r
82#\r
83# Returns:\r
84# The contents of the register in which the entry point is passed.\r
85#\r
86.global _EbcLLGetEbcEntryPoint;\r
87_EbcLLGetEbcEntryPoint:\r
88 ret\r
89\r
90#/*++\r
91#\r
92#Routine Description:\r
7b414b4e 93#\r
53c71d09 94# Return the caller's value of the stack pointer.\r
95#\r
96#Arguments:\r
97#\r
98# None.\r
99#\r
100#Returns:\r
101#\r
102# The current value of the stack pointer for the caller. We\r
103# adjust it by 4 here because when they called us, the return address\r
104# is put on the stack, thereby lowering it by 4 bytes.\r
105#\r
106#--*/\r
107\r
7b414b4e 108# UINTN EbcLLGetStackPointer()\r
53c71d09 109.global _EbcLLGetStackPointer;\r
110_EbcLLGetStackPointer:\r
111 mov %rsp, %rax\r
112 # Stack adjusted by this much when we were called,\r
113 # For this function, it's 4.\r
114 add $4, %rax\r
115 ret\r
116\r
117.global _EbcLLGetReturnValue;\r
118_EbcLLGetReturnValue:\r
119# UINT64 EbcLLGetReturnValue(VOID);\r
120# Routine Description:\r
121# When EBC calls native, on return the VM has to stuff the return\r
122# value into a VM register. It's assumed here that the value is still\r
123# in the register, so simply return and the caller should get the\r
124# return result properly.\r
125#\r
126# Arguments:\r
127# None.\r
128#\r
129# Returns:\r
130# The unmodified value returned by the native code.\r
131#\r
132 ret\r