| page ,132 | |
| title VM ASSEMBLY LANGUAGE ROUTINES | |
| ;**************************************************************************** | |
| ;* | |
| ;* Copyright (c) 2006, 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. | |
| ;* | |
| ;**************************************************************************** | |
| ;**************************************************************************** | |
| ; REV 1.0 | |
| ;**************************************************************************** | |
| ; | |
| ; Rev Date Description | |
| ; --- -------- ------------------------------------------------------------ | |
| ; 1.0 05/09/12 Initial creation of file. | |
| ; | |
| ;**************************************************************************** | |
| ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
| ; This code provides low level routines that support the Virtual Machine | |
| ; for option ROMs. | |
| ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
| ;--------------------------------------------------------------------------- | |
| ; Equate files needed. | |
| ;--------------------------------------------------------------------------- | |
| text SEGMENT | |
| ;--------------------------------------------------------------------------- | |
| ;;GenericPostSegment SEGMENT USE16 | |
| ;--------------------------------------------------------------------------- | |
| ;**************************************************************************** | |
| ; EbcLLCALLEX | |
| ; | |
| ; This function is called to execute an EBC CALLEX instruction. | |
| ; This instruction requires that we thunk out to external native | |
| ; code. For x64, we switch stacks, copy the arguments to the stack | |
| ; and jump to the specified function. | |
| ; On return, we restore the stack pointer to its original location. | |
| ; | |
| ; Destroys no working registers. | |
| ;**************************************************************************** | |
| ; VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr) | |
| CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD | |
| EbcLLCALLEXNative PROC NEAR PUBLIC | |
| push rbp | |
| push rbx | |
| mov rbp, rsp | |
| ; Function prolog | |
| ; Copy FuncAddr to a preserved register. | |
| mov rbx, rcx | |
| ; Set stack pointer to new value | |
| sub r8, rdx | |
| sub rsp, r8 | |
| mov rcx, rsp | |
| sub rsp, 20h | |
| call CopyMem | |
| add rsp, 20h | |
| ; Considering the worst case, load 4 potiential arguments | |
| ; into registers. | |
| mov rcx, qword ptr [rsp] | |
| mov rdx, qword ptr [rsp+8h] | |
| mov r8, qword ptr [rsp+10h] | |
| mov r9, qword ptr [rsp+18h] | |
| ; Now call the external routine | |
| call rbx | |
| ; Function epilog | |
| mov rsp, rbp | |
| pop rbx | |
| pop rbp | |
| ret | |
| EbcLLCALLEXNative ENDP | |
| ; UINTN EbcLLGetEbcEntryPoint(VOID); | |
| ; Routine Description: | |
| ; The VM thunk code stuffs an EBC entry point into a processor | |
| ; register. Since we can't use inline assembly to get it from | |
| ; the interpreter C code, stuff it into the return value | |
| ; register and return. | |
| ; | |
| ; Arguments: | |
| ; None. | |
| ; | |
| ; Returns: | |
| ; The contents of the register in which the entry point is passed. | |
| ; | |
| EbcLLGetEbcEntryPoint PROC NEAR PUBLIC | |
| ret | |
| EbcLLGetEbcEntryPoint ENDP | |
| ;/*++ | |
| ; | |
| ;Routine Description: | |
| ; | |
| ; Return the caller's value of the stack pointer. | |
| ; | |
| ;Arguments: | |
| ; | |
| ; None. | |
| ; | |
| ;Returns: | |
| ; | |
| ; The current value of the stack pointer for the caller. We | |
| ; adjust it by 4 here because when they called us, the return address | |
| ; is put on the stack, thereby lowering it by 4 bytes. | |
| ; | |
| ;--*/ | |
| ; UINTN EbcLLGetStackPointer() | |
| EbcLLGetStackPointer PROC NEAR PUBLIC | |
| mov rax, rsp ; get current stack pointer | |
| ; Stack adjusted by this much when we were called, | |
| ; For this function, it's 4. | |
| add rax, 4 | |
| ret | |
| EbcLLGetStackPointer ENDP | |
| ; UINT64 EbcLLGetReturnValue(VOID); | |
| ; Routine Description: | |
| ; When EBC calls native, on return the VM has to stuff the return | |
| ; value into a VM register. It's assumed here that the value is still | |
| ; in the register, so simply return and the caller should get the | |
| ; return result properly. | |
| ; | |
| ; Arguments: | |
| ; None. | |
| ; | |
| ; Returns: | |
| ; The unmodified value returned by the native code. | |
| ; | |
| EbcLLGetReturnValue PROC NEAR PUBLIC | |
| ret | |
| EbcLLGetReturnValue ENDP | |
| text ENDS | |
| END | |