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