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 27CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD 28EbcInterpret PROTO 29ExecuteEbcImageEntryPoint 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) 43EbcLLCALLEXNative 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 69skip_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 102EbcLLCALLEXNative ENDP 103 104;**************************************************************************** 105; EbcLLEbcInterpret 106; 107; Begin executing an EBC image. 108;**************************************************************************** 109; UINT64 EbcLLEbcInterpret(VOID) 110EbcLLEbcInterpret 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 195EbcLLEbcInterpret ENDP 196 197;**************************************************************************** 198; EbcLLExecuteEbcImageEntryPoint 199; 200; Begin executing an EBC image. 201;**************************************************************************** 202; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID) 203EbcLLExecuteEbcImageEntryPoint 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 243EbcLLExecuteEbcImageEntryPoint ENDP 244 245END 246 247