| ;/** @file | |
| ; | |
| ; This code provides low level routines that support the Virtual Machine | |
| ; for option ROMs. | |
| ; | |
| ; Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> | |
| ; This program and the accompanying materials | |
| ; are licensed and made available under the terms and conditions of the BSD License | |
| ; which accompanies this distribution. The full text of the license may be found at | |
| ; http://opensource.org/licenses/bsd-license.php | |
| ; | |
| ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| ; | |
| ;**/ | |
| page ,132 | |
| title VM ASSEMBLY LANGUAGE ROUTINES | |
| ;--------------------------------------------------------------------------- | |
| ; Equate files needed. | |
| ;--------------------------------------------------------------------------- | |
| .XLIST | |
| .LIST | |
| ;--------------------------------------------------------------------------- | |
| ; Assembler options | |
| ;--------------------------------------------------------------------------- | |
| .686p | |
| .model flat, C | |
| .code | |
| CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD | |
| EbcInterpret PROTO | |
| ExecuteEbcImageEntryPoint PROTO | |
| ;**************************************************************************** | |
| ; EbcLLCALLEXNative | |
| ; | |
| ; This function is called to execute an EBC CALLEX instruction | |
| ; to native code. | |
| ; This instruction requires that we thunk out to external native | |
| ; code. For IA32, we simply switch stacks and jump to the | |
| ; specified function. On return, we restore the stack pointer | |
| ; to its original location. | |
| ; | |
| ; Destroys no working registers. | |
| ;**************************************************************************** | |
| ; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr) | |
| EbcLLCALLEXNative PROC PUBLIC | |
| push ebp | |
| push ebx | |
| mov ebp, esp ; standard function prolog | |
| ; Get function address in a register | |
| ; mov ecx, FuncAddr => mov ecx, dword ptr [FuncAddr] | |
| mov ecx, dword ptr [esp + 0Ch] | |
| ; Set stack pointer to new value | |
| ; mov eax, NewStackPointer => mov eax, dword ptr [NewSp] | |
| mov eax, dword ptr [esp + 14h] | |
| mov edx, dword ptr [esp + 10h] | |
| sub eax, edx | |
| sub esp, eax | |
| mov ebx, esp | |
| push ecx | |
| push eax | |
| push edx | |
| push ebx | |
| call CopyMem | |
| pop eax | |
| pop eax | |
| pop eax | |
| pop ecx | |
| ; Now call the external routine | |
| call ecx | |
| ; ebp is preserved by the callee. In this function it | |
| ; equals the original esp, so set them equal | |
| mov esp, ebp | |
| ; Standard function epilog | |
| mov esp, ebp | |
| pop ebx | |
| pop ebp | |
| ret | |
| EbcLLCALLEXNative ENDP | |
| ;**************************************************************************** | |
| ; EbcLLEbcInterpret | |
| ; | |
| ; Begin executing an EBC image. | |
| ;**************************************************************************** | |
| ; UINT64 EbcLLEbcInterpret(VOID) | |
| EbcLLEbcInterpret PROC PUBLIC | |
| ; | |
| ;; mov eax, 0xca112ebc | |
| ;; mov eax, EbcEntryPoint | |
| ;; mov ecx, EbcLLEbcInterpret | |
| ;; jmp ecx | |
| ; | |
| ; Caller uses above instruction to jump here | |
| ; The stack is below: | |
| ; +-----------+ | |
| ; | RetAddr | | |
| ; +-----------+ | |
| ; |EntryPoint | (EAX) | |
| ; +-----------+ | |
| ; | Arg1 | <- EDI | |
| ; +-----------+ | |
| ; | Arg2 | | |
| ; +-----------+ | |
| ; | ... | | |
| ; +-----------+ | |
| ; | Arg16 | | |
| ; +-----------+ | |
| ; | EDI | | |
| ; +-----------+ | |
| ; | ESI | | |
| ; +-----------+ | |
| ; | EBP | <- EBP | |
| ; +-----------+ | |
| ; | RetAddr | <- ESP is here | |
| ; +-----------+ | |
| ; | Arg1 | <- ESI | |
| ; +-----------+ | |
| ; | Arg2 | | |
| ; +-----------+ | |
| ; | ... | | |
| ; +-----------+ | |
| ; | Arg16 | | |
| ; +-----------+ | |
| ; | |
| ; Construct new stack | |
| push ebp | |
| mov ebp, esp | |
| push esi | |
| push edi | |
| sub esp, 40h | |
| push eax | |
| mov esi, ebp | |
| add esi, 8 | |
| mov edi, esp | |
| add edi, 4 | |
| mov ecx, 16 | |
| rep movsd | |
| ; call C-code | |
| call EbcInterpret | |
| add esp, 44h | |
| pop edi | |
| pop esi | |
| pop ebp | |
| ret | |
| EbcLLEbcInterpret ENDP | |
| ;**************************************************************************** | |
| ; EbcLLExecuteEbcImageEntryPoint | |
| ; | |
| ; Begin executing an EBC image. | |
| ;**************************************************************************** | |
| ; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID) | |
| EbcLLExecuteEbcImageEntryPoint PROC PUBLIC | |
| ; | |
| ;; mov eax, 0xca112ebc | |
| ;; mov eax, EbcEntryPoint | |
| ;; mov ecx, EbcLLExecuteEbcImageEntryPoint | |
| ;; jmp ecx | |
| ; | |
| ; Caller uses above instruction to jump here | |
| ; The stack is below: | |
| ; +-----------+ | |
| ; | RetAddr | | |
| ; +-----------+ | |
| ; |EntryPoint | (EAX) | |
| ; +-----------+ | |
| ; |ImageHandle| | |
| ; +-----------+ | |
| ; |SystemTable| | |
| ; +-----------+ | |
| ; | RetAddr | <- ESP is here | |
| ; +-----------+ | |
| ; |ImageHandle| | |
| ; +-----------+ | |
| ; |SystemTable| | |
| ; +-----------+ | |
| ; | |
| ; Construct new stack | |
| mov [esp - 0Ch], eax | |
| mov eax, [esp + 04h] | |
| mov [esp - 08h], eax | |
| mov eax, [esp + 08h] | |
| mov [esp - 04h], eax | |
| ; call C-code | |
| sub esp, 0Ch | |
| call ExecuteEbcImageEntryPoint | |
| add esp, 0Ch | |
| ret | |
| EbcLLExecuteEbcImageEntryPoint ENDP | |
| END |