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 25 SECTION .text 26 extern ASM_PFX(CopyMem) 27 extern ASM_PFX(EbcInterpret) 28 extern 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) 43 global ASM_PFX(EbcLLCALLEXNative) 44 ASM_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) 89 global ASM_PFX(EbcLLEbcInterpret) 90 ASM_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) 158 global ASM_PFX(EbcLLExecuteEbcImageEntryPoint) 159 ASM_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