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; 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.XLIST 25 26.LIST 27 28;--------------------------------------------------------------------------- 29; Assembler options 30;--------------------------------------------------------------------------- 31 32.686p 33.model flat, C 34.code 35CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD 36EbcInterpret PROTO 37ExecuteEbcImageEntryPoint PROTO 38 39;**************************************************************************** 40; EbcLLCALLEXNative 41; 42; This function is called to execute an EBC CALLEX instruction 43; to native code. 44; This instruction requires that we thunk out to external native 45; code. For IA32, we simply switch stacks and jump to the 46; specified function. On return, we restore the stack pointer 47; to its original location. 48; 49; Destroys no working registers. 50;**************************************************************************** 51; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr) 52EbcLLCALLEXNative PROC PUBLIC 53 push ebp 54 push ebx 55 mov ebp, esp ; standard function prolog 56 57 ; Get function address in a register 58 ; mov ecx, FuncAddr => mov ecx, dword ptr [FuncAddr] 59 mov ecx, dword ptr [esp + 0Ch] 60 61 ; Set stack pointer to new value 62 ; mov eax, NewStackPointer => mov eax, dword ptr [NewSp] 63 mov eax, dword ptr [esp + 14h] 64 mov edx, dword ptr [esp + 10h] 65 sub eax, edx 66 sub esp, eax 67 mov ebx, esp 68 push ecx 69 push eax 70 push edx 71 push ebx 72 call CopyMem 73 pop eax 74 pop eax 75 pop eax 76 pop ecx 77 78 ; Now call the external routine 79 call ecx 80 81 ; ebp is preserved by the callee. In this function it 82 ; equals the original esp, so set them equal 83 mov esp, ebp 84 85 ; Standard function epilog 86 mov esp, ebp 87 pop ebx 88 pop ebp 89 ret 90EbcLLCALLEXNative ENDP 91 92;**************************************************************************** 93; EbcLLEbcInterpret 94; 95; Begin executing an EBC image. 96;**************************************************************************** 97; UINT64 EbcLLEbcInterpret(VOID) 98EbcLLEbcInterpret PROC PUBLIC 99 ; 100 ;; mov eax, 0xca112ebc 101 ;; mov eax, EbcEntryPoint 102 ;; mov ecx, EbcLLEbcInterpret 103 ;; jmp ecx 104 ; 105 ; Caller uses above instruction to jump here 106 ; The stack is below: 107 ; +-----------+ 108 ; | RetAddr | 109 ; +-----------+ 110 ; |EntryPoint | (EAX) 111 ; +-----------+ 112 ; | Arg1 | <- EDI 113 ; +-----------+ 114 ; | Arg2 | 115 ; +-----------+ 116 ; | ... | 117 ; +-----------+ 118 ; | Arg16 | 119 ; +-----------+ 120 ; | EDI | 121 ; +-----------+ 122 ; | ESI | 123 ; +-----------+ 124 ; | EBP | <- EBP 125 ; +-----------+ 126 ; | RetAddr | <- ESP is here 127 ; +-----------+ 128 ; | Arg1 | <- ESI 129 ; +-----------+ 130 ; | Arg2 | 131 ; +-----------+ 132 ; | ... | 133 ; +-----------+ 134 ; | Arg16 | 135 ; +-----------+ 136 ; 137 138 ; Construct new stack 139 push ebp 140 mov ebp, esp 141 push esi 142 push edi 143 sub esp, 40h 144 push eax 145 mov esi, ebp 146 add esi, 8 147 mov edi, esp 148 add edi, 4 149 mov ecx, 16 150 rep movsd 151 152 ; call C-code 153 call EbcInterpret 154 add esp, 44h 155 pop edi 156 pop esi 157 pop ebp 158 ret 159EbcLLEbcInterpret ENDP 160 161;**************************************************************************** 162; EbcLLExecuteEbcImageEntryPoint 163; 164; Begin executing an EBC image. 165;**************************************************************************** 166; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID) 167EbcLLExecuteEbcImageEntryPoint PROC PUBLIC 168 ; 169 ;; mov eax, 0xca112ebc 170 ;; mov eax, EbcEntryPoint 171 ;; mov ecx, EbcLLExecuteEbcImageEntryPoint 172 ;; jmp ecx 173 ; 174 ; Caller uses above instruction to jump here 175 ; The stack is below: 176 ; +-----------+ 177 ; | RetAddr | 178 ; +-----------+ 179 ; |EntryPoint | (EAX) 180 ; +-----------+ 181 ; |ImageHandle| 182 ; +-----------+ 183 ; |SystemTable| 184 ; +-----------+ 185 ; | RetAddr | <- ESP is here 186 ; +-----------+ 187 ; |ImageHandle| 188 ; +-----------+ 189 ; |SystemTable| 190 ; +-----------+ 191 ; 192 193 ; Construct new stack 194 mov [esp - 0Ch], eax 195 mov eax, [esp + 04h] 196 mov [esp - 08h], eax 197 mov eax, [esp + 08h] 198 mov [esp - 04h], eax 199 200 ; call C-code 201 sub esp, 0Ch 202 call ExecuteEbcImageEntryPoint 203 add esp, 0Ch 204 ret 205EbcLLExecuteEbcImageEntryPoint ENDP 206 207END 208