;/** @file ; ; This code provides low level routines that support the Virtual Machine ; for option ROMs. ; ; Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
; 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