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