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