Home | History | Annotate | Download | only in X64
      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 ;  Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>
      8 ;  This program and the accompanying materials
      9 ;  are licensed and made available under the terms and conditions of the BSD License
     10 ;  which accompanies this distribution.  The full text of the license may be found at
     11 ;  http://opensource.org/licenses/bsd-license.php
     12 ;
     13 ;  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     14 ;  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     15 ;
     16 ;**/
     17 
     18 ;---------------------------------------------------------------------------
     19 ; Equate files needed.
     20 ;---------------------------------------------------------------------------
     21 
     22 DEFAULT REL
     23 SECTION .text
     24 
     25 extern ASM_PFX(CopyMem)
     26 extern ASM_PFX(EbcInterpret)
     27 extern ASM_PFX(ExecuteEbcImageEntryPoint)
     28 
     29 ;****************************************************************************
     30 ; EbcLLCALLEX
     31 ;
     32 ; This function is called to execute an EBC CALLEX instruction.
     33 ; This instruction requires that we thunk out to external native
     34 ; code. For x64, we switch stacks, copy the arguments to the stack
     35 ; and jump to the specified function.
     36 ; On return, we restore the stack pointer to its original location.
     37 ;
     38 ; Destroys no working registers.
     39 ;****************************************************************************
     40 ; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
     41 global ASM_PFX(EbcLLCALLEXNative)
     42 ASM_PFX(EbcLLCALLEXNative):
     43       push   rbp
     44       push   rbx
     45       mov    rbp, rsp
     46       ; Function prolog
     47 
     48       ; Copy FuncAddr to a preserved register.
     49       mov    rbx, rcx
     50 
     51       ; Set stack pointer to new value
     52       sub    r8,  rdx
     53 
     54       ;
     55       ; Fix X64 native function call prolog. Prepare space for at least 4 arguments,
     56       ; even if the native function's arguments are less than 4.
     57       ;
     58       ; From MSDN x64 Software Conventions, Overview of x64 Calling Conventions:
     59       ;   "The caller is responsible for allocating space for parameters to the
     60       ;   callee, and must always allocate sufficient space for the 4 register
     61       ;   parameters, even if the callee doesn't have that many parameters.
     62       ;   This aids in the simplicity of supporting C unprototyped functions,
     63       ;   and vararg C/C++ functions."
     64       ;
     65       cmp    r8, 0x20
     66       jae    skip_expansion
     67       mov    r8, dword 0x20
     68 skip_expansion:
     69 
     70       sub    rsp, r8
     71 
     72       ;
     73       ; Fix X64 native function call 16-byte alignment.
     74       ;
     75       ; From MSDN x64 Software Conventions, Stack Usage:
     76       ;   "The stack will always be maintained 16-byte aligned, except within
     77       ;   the prolog (for example, after the return address is pushed)."
     78       ;
     79       and    rsp, ~ 0xf
     80 
     81       mov    rcx, rsp
     82       sub    rsp, 0x20
     83       call   ASM_PFX(CopyMem)
     84       add    rsp, 0x20
     85 
     86       ; Considering the worst case, load 4 potiential arguments
     87       ; into registers.
     88       mov    rcx, qword [rsp]
     89       mov    rdx, qword [rsp+0x8]
     90       mov    r8,  qword [rsp+0x10]
     91       mov    r9,  qword [rsp+0x18]
     92 
     93       ; Now call the external routine
     94       call  rbx
     95 
     96       ; Function epilog
     97       mov      rsp, rbp
     98       pop      rbx
     99       pop      rbp
    100       ret
    101 
    102 ;****************************************************************************
    103 ; EbcLLEbcInterpret
    104 ;
    105 ; Begin executing an EBC image.
    106 ;****************************************************************************
    107 ; UINT64 EbcLLEbcInterpret(VOID)
    108 global ASM_PFX(EbcLLEbcInterpret)
    109 ASM_PFX(EbcLLEbcInterpret):
    110     ;
    111     ;; mov rax, ca112ebccall2ebch
    112     ;; mov r10, EbcEntryPoint
    113     ;; mov r11, EbcLLEbcInterpret
    114     ;; jmp r11
    115     ;
    116     ; Caller uses above instruction to jump here
    117     ; The stack is below:
    118     ; +-----------+
    119     ; |  RetAddr  |
    120     ; +-----------+
    121     ; |EntryPoint | (R10)
    122     ; +-----------+
    123     ; |   Arg1    | <- RDI
    124     ; +-----------+
    125     ; |   Arg2    |
    126     ; +-----------+
    127     ; |   ...     |
    128     ; +-----------+
    129     ; |   Arg16   |
    130     ; +-----------+
    131     ; |   Dummy   |
    132     ; +-----------+
    133     ; |   RDI     |
    134     ; +-----------+
    135     ; |   RSI     |
    136     ; +-----------+
    137     ; |   RBP     | <- RBP
    138     ; +-----------+
    139     ; |  RetAddr  | <- RSP is here
    140     ; +-----------+
    141     ; |  Scratch1 | (RCX) <- RSI
    142     ; +-----------+
    143     ; |  Scratch2 | (RDX)
    144     ; +-----------+
    145     ; |  Scratch3 | (R8)
    146     ; +-----------+
    147     ; |  Scratch4 | (R9)
    148     ; +-----------+
    149     ; |   Arg5    |
    150     ; +-----------+
    151     ; |   Arg6    |
    152     ; +-----------+
    153     ; |   ...     |
    154     ; +-----------+
    155     ; |   Arg16   |
    156     ; +-----------+
    157     ;
    158 
    159     ; save old parameter to stack
    160     mov  [rsp + 0x8], rcx
    161     mov  [rsp + 0x10], rdx
    162     mov  [rsp + 0x18], r8
    163     mov  [rsp + 0x20], r9
    164 
    165     ; Construct new stack
    166     push rbp
    167     mov  rbp, rsp
    168     push rsi
    169     push rdi
    170     push rbx
    171     sub  rsp, 0x80
    172     push r10
    173     mov  rsi, rbp
    174     add  rsi, 0x10
    175     mov  rdi, rsp
    176     add  rdi, 8
    177     mov  rcx, dword 16
    178     rep  movsq
    179 
    180     ; build new paramater calling convention
    181     mov  r9,  [rsp + 0x18]
    182     mov  r8,  [rsp + 0x10]
    183     mov  rdx, [rsp + 0x8]
    184     mov  rcx, r10
    185 
    186     ; call C-code
    187     call ASM_PFX(EbcInterpret)
    188     add  rsp, 0x88
    189     pop  rbx
    190     pop  rdi
    191     pop  rsi
    192     pop  rbp
    193     ret
    194 
    195 ;****************************************************************************
    196 ; EbcLLExecuteEbcImageEntryPoint
    197 ;
    198 ; Begin executing an EBC image.
    199 ;****************************************************************************
    200 ; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)
    201 global ASM_PFX(EbcLLExecuteEbcImageEntryPoint)
    202 ASM_PFX(EbcLLExecuteEbcImageEntryPoint):
    203     ;
    204     ;; mov rax, ca112ebccall2ebch
    205     ;; mov r10, EbcEntryPoint
    206     ;; mov r11, EbcLLExecuteEbcImageEntryPoint
    207     ;; jmp r11
    208     ;
    209     ; Caller uses above instruction to jump here
    210     ; The stack is below:
    211     ; +-----------+
    212     ; |  RetAddr  |
    213     ; +-----------+
    214     ; |EntryPoint | (R10)
    215     ; +-----------+
    216     ; |ImageHandle|
    217     ; +-----------+
    218     ; |SystemTable|
    219     ; +-----------+
    220     ; |   Dummy   |
    221     ; +-----------+
    222     ; |   Dummy   |
    223     ; +-----------+
    224     ; |  RetAddr  | <- RSP is here
    225     ; +-----------+
    226     ; |ImageHandle| (RCX)
    227     ; +-----------+
    228     ; |SystemTable| (RDX)
    229     ; +-----------+
    230     ;
    231 
    232     ; build new paramater calling convention
    233     mov  r8, rdx
    234     mov  rdx, rcx
    235     mov  rcx, r10
    236 
    237     ; call C-code
    238     sub  rsp, 0x28
    239     call ASM_PFX(ExecuteEbcImageEntryPoint)
    240     add  rsp, 0x28
    241     ret
    242 
    243