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