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