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