]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/EbcDxe/X64/EbcLowLevel.asm
MdeModulePkg/EbcDxe: rebase to ARRAY_SIZE()
[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 - 2011, Intel Corporation. All rights reserved.<BR>
7 ; Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>
8 ; This program and the accompanying materials
9 ; are licensed and made available under the terms and conditions of the BSD License
10 ; which accompanies this distribution. The full text of the license may be found at
11 ; http://opensource.org/licenses/bsd-license.php
12 ;
13 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 ;
16 ;**/
17
18 page ,132
19 title VM ASSEMBLY LANGUAGE ROUTINES
20
21 ;---------------------------------------------------------------------------
22 ; Equate files needed.
23 ;---------------------------------------------------------------------------
24
25 .CODE
26
27 CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
28 EbcInterpret PROTO
29 ExecuteEbcImageEntryPoint PROTO
30
31 ;****************************************************************************
32 ; EbcLLCALLEX
33 ;
34 ; This function is called to execute an EBC CALLEX instruction.
35 ; This instruction requires that we thunk out to external native
36 ; code. For x64, we switch stacks, copy the arguments to the stack
37 ; and jump to the specified function.
38 ; On return, we restore the stack pointer to its original location.
39 ;
40 ; Destroys no working registers.
41 ;****************************************************************************
42 ; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
43 EbcLLCALLEXNative PROC PUBLIC
44 push rbp
45 push rbx
46 mov rbp, rsp
47 ; Function prolog
48
49 ; Copy FuncAddr to a preserved register.
50 mov rbx, rcx
51
52 ; Set stack pointer to new value
53 sub r8, rdx
54
55 ;
56 ; Fix X64 native function call prolog. Prepare space for at least 4 arguments,
57 ; even if the native function's arguments are less than 4.
58 ;
59 ; From MSDN x64 Software Conventions, Overview of x64 Calling Conventions:
60 ; "The caller is responsible for allocating space for parameters to the
61 ; callee, and must always allocate sufficient space for the 4 register
62 ; parameters, even if the callee doesn't have that many parameters.
63 ; This aids in the simplicity of supporting C unprototyped functions,
64 ; and vararg C/C++ functions."
65 ;
66 cmp r8, 20h
67 jae skip_expansion
68 mov r8, 20h
69 skip_expansion:
70
71 sub rsp, r8
72
73 ;
74 ; Fix X64 native function call 16-byte alignment.
75 ;
76 ; From MSDN x64 Software Conventions, Stack Usage:
77 ; "The stack will always be maintained 16-byte aligned, except within
78 ; the prolog (for example, after the return address is pushed)."
79 ;
80 and rsp, NOT 0fh
81
82 mov rcx, rsp
83 sub rsp, 20h
84 call CopyMem
85 add rsp, 20h
86
87 ; Considering the worst case, load 4 potiential arguments
88 ; into registers.
89 mov rcx, qword ptr [rsp]
90 mov rdx, qword ptr [rsp+8h]
91 mov r8, qword ptr [rsp+10h]
92 mov r9, qword ptr [rsp+18h]
93
94 ; Now call the external routine
95 call rbx
96
97 ; Function epilog
98 mov rsp, rbp
99 pop rbx
100 pop rbp
101 ret
102 EbcLLCALLEXNative ENDP
103
104 ;****************************************************************************
105 ; EbcLLEbcInterpret
106 ;
107 ; Begin executing an EBC image.
108 ;****************************************************************************
109 ; UINT64 EbcLLEbcInterpret(VOID)
110 EbcLLEbcInterpret PROC PUBLIC
111 ;
112 ;; mov rax, ca112ebccall2ebch
113 ;; mov r10, EbcEntryPoint
114 ;; mov r11, EbcLLEbcInterpret
115 ;; jmp r11
116 ;
117 ; Caller uses above instruction to jump here
118 ; The stack is below:
119 ; +-----------+
120 ; | RetAddr |
121 ; +-----------+
122 ; |EntryPoint | (R10)
123 ; +-----------+
124 ; | Arg1 | <- RDI
125 ; +-----------+
126 ; | Arg2 |
127 ; +-----------+
128 ; | ... |
129 ; +-----------+
130 ; | Arg16 |
131 ; +-----------+
132 ; | Dummy |
133 ; +-----------+
134 ; | RDI |
135 ; +-----------+
136 ; | RSI |
137 ; +-----------+
138 ; | RBP | <- RBP
139 ; +-----------+
140 ; | RetAddr | <- RSP is here
141 ; +-----------+
142 ; | Scratch1 | (RCX) <- RSI
143 ; +-----------+
144 ; | Scratch2 | (RDX)
145 ; +-----------+
146 ; | Scratch3 | (R8)
147 ; +-----------+
148 ; | Scratch4 | (R9)
149 ; +-----------+
150 ; | Arg5 |
151 ; +-----------+
152 ; | Arg6 |
153 ; +-----------+
154 ; | ... |
155 ; +-----------+
156 ; | Arg16 |
157 ; +-----------+
158 ;
159
160 ; save old parameter to stack
161 mov [rsp + 08h], rcx
162 mov [rsp + 10h], rdx
163 mov [rsp + 18h], r8
164 mov [rsp + 20h], r9
165
166 ; Construct new stack
167 push rbp
168 mov rbp, rsp
169 push rsi
170 push rdi
171 push rbx
172 sub rsp, 80h
173 push r10
174 mov rsi, rbp
175 add rsi, 10h
176 mov rdi, rsp
177 add rdi, 8
178 mov rcx, 16
179 rep movsq
180
181 ; build new paramater calling convention
182 mov r9, [rsp + 18h]
183 mov r8, [rsp + 10h]
184 mov rdx, [rsp + 08h]
185 mov rcx, r10
186
187 ; call C-code
188 call EbcInterpret
189 add rsp, 88h
190 pop rbx
191 pop rdi
192 pop rsi
193 pop rbp
194 ret
195 EbcLLEbcInterpret ENDP
196
197 ;****************************************************************************
198 ; EbcLLExecuteEbcImageEntryPoint
199 ;
200 ; Begin executing an EBC image.
201 ;****************************************************************************
202 ; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)
203 EbcLLExecuteEbcImageEntryPoint PROC PUBLIC
204 ;
205 ;; mov rax, ca112ebccall2ebch
206 ;; mov r10, EbcEntryPoint
207 ;; mov r11, EbcLLExecuteEbcImageEntryPoint
208 ;; jmp r11
209 ;
210 ; Caller uses above instruction to jump here
211 ; The stack is below:
212 ; +-----------+
213 ; | RetAddr |
214 ; +-----------+
215 ; |EntryPoint | (R10)
216 ; +-----------+
217 ; |ImageHandle|
218 ; +-----------+
219 ; |SystemTable|
220 ; +-----------+
221 ; | Dummy |
222 ; +-----------+
223 ; | Dummy |
224 ; +-----------+
225 ; | RetAddr | <- RSP is here
226 ; +-----------+
227 ; |ImageHandle| (RCX)
228 ; +-----------+
229 ; |SystemTable| (RDX)
230 ; +-----------+
231 ;
232
233 ; build new paramater calling convention
234 mov r8, rdx
235 mov rdx, rcx
236 mov rcx, r10
237
238 ; call C-code
239 sub rsp, 28h
240 call ExecuteEbcImageEntryPoint
241 add rsp, 28h
242 ret
243 EbcLLExecuteEbcImageEntryPoint ENDP
244
245 END
246