]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/EbcDxe/X64/EbcLowLevel.nasm
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / X64 / EbcLowLevel.nasm
1 ;/** @file
2 ;
3 ; This code provides low level routines that support the Virtual Machine.
4 ; for option ROMs.
5 ;
6 ; Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
7 ; Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>
8 ; SPDX-License-Identifier: BSD-2-Clause-Patent
9 ;
10 ;**/
11
12 ;---------------------------------------------------------------------------
13 ; Equate files needed.
14 ;---------------------------------------------------------------------------
15
16 DEFAULT REL
17 SECTION .text
18
19 extern ASM_PFX(CopyMem)
20 extern ASM_PFX(EbcInterpret)
21 extern ASM_PFX(ExecuteEbcImageEntryPoint)
22
23 ;****************************************************************************
24 ; EbcLLCALLEX
25 ;
26 ; This function is called to execute an EBC CALLEX instruction.
27 ; This instruction requires that we thunk out to external native
28 ; code. For x64, we switch stacks, copy the arguments to the stack
29 ; and jump to the specified function.
30 ; On return, we restore the stack pointer to its original location.
31 ;
32 ; Destroys no working registers.
33 ;****************************************************************************
34 ; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
35 global ASM_PFX(EbcLLCALLEXNative)
36 ASM_PFX(EbcLLCALLEXNative):
37 push rbp
38 push rbx
39 mov rbp, rsp
40 ; Function prolog
41
42 ; Copy FuncAddr to a preserved register.
43 mov rbx, rcx
44
45 ; Set stack pointer to new value
46 sub r8, rdx
47
48 ;
49 ; Fix X64 native function call prolog. Prepare space for at least 4 arguments,
50 ; even if the native function's arguments are less than 4.
51 ;
52 ; From MSDN x64 Software Conventions, Overview of x64 Calling Conventions:
53 ; "The caller is responsible for allocating space for parameters to the
54 ; callee, and must always allocate sufficient space for the 4 register
55 ; parameters, even if the callee doesn't have that many parameters.
56 ; This aids in the simplicity of supporting C unprototyped functions,
57 ; and vararg C/C++ functions."
58 ;
59 cmp r8, 0x20
60 jae skip_expansion
61 mov r8, dword 0x20
62 skip_expansion:
63
64 sub rsp, r8
65
66 ;
67 ; Fix X64 native function call 16-byte alignment.
68 ;
69 ; From MSDN x64 Software Conventions, Stack Usage:
70 ; "The stack will always be maintained 16-byte aligned, except within
71 ; the prolog (for example, after the return address is pushed)."
72 ;
73 and rsp, ~ 0xf
74
75 mov rcx, rsp
76 sub rsp, 0x20
77 call ASM_PFX(CopyMem)
78 add rsp, 0x20
79
80 ; Considering the worst case, load 4 potiential arguments
81 ; into registers.
82 mov rcx, qword [rsp]
83 mov rdx, qword [rsp+0x8]
84 mov r8, qword [rsp+0x10]
85 mov r9, qword [rsp+0x18]
86
87 ; Now call the external routine
88 call rbx
89
90 ; Function epilog
91 mov rsp, rbp
92 pop rbx
93 pop rbp
94 ret
95
96 ;****************************************************************************
97 ; EbcLLEbcInterpret
98 ;
99 ; Begin executing an EBC image.
100 ;****************************************************************************
101 ; UINT64 EbcLLEbcInterpret(VOID)
102 global ASM_PFX(EbcLLEbcInterpret)
103 ASM_PFX(EbcLLEbcInterpret):
104 ;
105 ;; mov rax, ca112ebccall2ebch
106 ;; mov r10, EbcEntryPoint
107 ;; mov r11, EbcLLEbcInterpret
108 ;; jmp r11
109 ;
110 ; Caller uses above instruction to jump here
111 ; The stack is below:
112 ; +-----------+
113 ; | RetAddr |
114 ; +-----------+
115 ; |EntryPoint | (R10)
116 ; +-----------+
117 ; | Arg1 | <- RDI
118 ; +-----------+
119 ; | Arg2 |
120 ; +-----------+
121 ; | ... |
122 ; +-----------+
123 ; | Arg16 |
124 ; +-----------+
125 ; | Dummy |
126 ; +-----------+
127 ; | RDI |
128 ; +-----------+
129 ; | RSI |
130 ; +-----------+
131 ; | RBP | <- RBP
132 ; +-----------+
133 ; | RetAddr | <- RSP is here
134 ; +-----------+
135 ; | Scratch1 | (RCX) <- RSI
136 ; +-----------+
137 ; | Scratch2 | (RDX)
138 ; +-----------+
139 ; | Scratch3 | (R8)
140 ; +-----------+
141 ; | Scratch4 | (R9)
142 ; +-----------+
143 ; | Arg5 |
144 ; +-----------+
145 ; | Arg6 |
146 ; +-----------+
147 ; | ... |
148 ; +-----------+
149 ; | Arg16 |
150 ; +-----------+
151 ;
152
153 ; save old parameter to stack
154 mov [rsp + 0x8], rcx
155 mov [rsp + 0x10], rdx
156 mov [rsp + 0x18], r8
157 mov [rsp + 0x20], r9
158
159 ; Construct new stack
160 push rbp
161 mov rbp, rsp
162 push rsi
163 push rdi
164 push rbx
165 sub rsp, 0x80
166 push r10
167 mov rsi, rbp
168 add rsi, 0x10
169 mov rdi, rsp
170 add rdi, 8
171 mov rcx, dword 16
172 rep movsq
173
174 ; build new paramater calling convention
175 mov r9, [rsp + 0x18]
176 mov r8, [rsp + 0x10]
177 mov rdx, [rsp + 0x8]
178 mov rcx, r10
179
180 ; call C-code
181 call ASM_PFX(EbcInterpret)
182 add rsp, 0x88
183 pop rbx
184 pop rdi
185 pop rsi
186 pop rbp
187 ret
188
189 ;****************************************************************************
190 ; EbcLLExecuteEbcImageEntryPoint
191 ;
192 ; Begin executing an EBC image.
193 ;****************************************************************************
194 ; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)
195 global ASM_PFX(EbcLLExecuteEbcImageEntryPoint)
196 ASM_PFX(EbcLLExecuteEbcImageEntryPoint):
197 ;
198 ;; mov rax, ca112ebccall2ebch
199 ;; mov r10, EbcEntryPoint
200 ;; mov r11, EbcLLExecuteEbcImageEntryPoint
201 ;; jmp r11
202 ;
203 ; Caller uses above instruction to jump here
204 ; The stack is below:
205 ; +-----------+
206 ; | RetAddr |
207 ; +-----------+
208 ; |EntryPoint | (R10)
209 ; +-----------+
210 ; |ImageHandle|
211 ; +-----------+
212 ; |SystemTable|
213 ; +-----------+
214 ; | Dummy |
215 ; +-----------+
216 ; | Dummy |
217 ; +-----------+
218 ; | RetAddr | <- RSP is here
219 ; +-----------+
220 ; |ImageHandle| (RCX)
221 ; +-----------+
222 ; |SystemTable| (RDX)
223 ; +-----------+
224 ;
225
226 ; build new paramater calling convention
227 mov r8, rdx
228 mov rdx, rcx
229 mov rcx, r10
230
231 ; call C-code
232 sub rsp, 0x28
233 call ASM_PFX(ExecuteEbcImageEntryPoint)
234 add rsp, 0x28
235 ret
236