Home | History | Annotate | Download | only in Ia32
      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 ;  This program and the accompanying materials
      8 ;  are licensed and made available under the terms and conditions of the BSD License
      9 ;  which accompanies this distribution.  The full text of the license may be found at
     10 ;  http://opensource.org/licenses/bsd-license.php
     11 ;
     12 ;  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13 ;  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 ;
     15 ;**/
     16 
     17 ;---------------------------------------------------------------------------
     18 ; Equate files needed.
     19 ;---------------------------------------------------------------------------
     20 
     21 ;---------------------------------------------------------------------------
     22 ; Assembler options
     23 ;---------------------------------------------------------------------------
     24 
     25 SECTION .text
     26 extern ASM_PFX(CopyMem)
     27 extern ASM_PFX(EbcInterpret)
     28 extern ASM_PFX(ExecuteEbcImageEntryPoint)
     29 
     30 ;****************************************************************************
     31 ; EbcLLCALLEXNative
     32 ;
     33 ; This function is called to execute an EBC CALLEX instruction
     34 ; to native code.
     35 ; This instruction requires that we thunk out to external native
     36 ; code. For IA32, we simply switch stacks and jump to the
     37 ; specified function. On return, we restore the stack pointer
     38 ; to its original location.
     39 ;
     40 ; Destroys no working registers.
     41 ;****************************************************************************
     42 ; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
     43 global ASM_PFX(EbcLLCALLEXNative)
     44 ASM_PFX(EbcLLCALLEXNative):
     45       push   ebp
     46       push   ebx
     47       mov    ebp, esp              ; standard function prolog
     48 
     49       ; Get function address in a register
     50       ; mov ecx, FuncAddr => mov ecx, dword ptr [FuncAddr]
     51       mov    ecx, dword [esp + 0xC]
     52 
     53       ; Set stack pointer to new value
     54       ; mov eax, NewStackPointer => mov eax, dword ptr [NewSp]
     55       mov    eax, dword [esp + 0x14]
     56       mov    edx, dword [esp + 0x10]
     57       sub    eax, edx
     58       sub    esp, eax
     59       mov    ebx, esp
     60       push   ecx
     61       push   eax
     62       push   edx
     63       push   ebx
     64       call   ASM_PFX(CopyMem)
     65       pop    eax
     66       pop    eax
     67       pop    eax
     68       pop    ecx
     69 
     70       ; Now call the external routine
     71       call  ecx
     72 
     73       ; ebp is preserved by the callee. In this function it
     74       ; equals the original esp, so set them equal
     75       mov    esp, ebp
     76 
     77       ; Standard function epilog
     78       mov      esp, ebp
     79       pop      ebx
     80       pop      ebp
     81       ret
     82 
     83 ;****************************************************************************
     84 ; EbcLLEbcInterpret
     85 ;
     86 ; Begin executing an EBC image.
     87 ;****************************************************************************
     88 ; UINT64 EbcLLEbcInterpret(VOID)
     89 global ASM_PFX(EbcLLEbcInterpret)
     90 ASM_PFX(EbcLLEbcInterpret):
     91     ;
     92     ;; mov eax, 0xca112ebc
     93     ;; mov eax, EbcEntryPoint
     94     ;; mov ecx, EbcLLEbcInterpret
     95     ;; jmp ecx
     96     ;
     97     ; Caller uses above instruction to jump here
     98     ; The stack is below:
     99     ; +-----------+
    100     ; |  RetAddr  |
    101     ; +-----------+
    102     ; |EntryPoint | (EAX)
    103     ; +-----------+
    104     ; |   Arg1    | <- EDI
    105     ; +-----------+
    106     ; |   Arg2    |
    107     ; +-----------+
    108     ; |   ...     |
    109     ; +-----------+
    110     ; |   Arg16   |
    111     ; +-----------+
    112     ; |   EDI     |
    113     ; +-----------+
    114     ; |   ESI     |
    115     ; +-----------+
    116     ; |   EBP     | <- EBP
    117     ; +-----------+
    118     ; |  RetAddr  | <- ESP is here
    119     ; +-----------+
    120     ; |   Arg1    | <- ESI
    121     ; +-----------+
    122     ; |   Arg2    |
    123     ; +-----------+
    124     ; |   ...     |
    125     ; +-----------+
    126     ; |   Arg16   |
    127     ; +-----------+
    128     ;
    129 
    130     ; Construct new stack
    131     push ebp
    132     mov  ebp, esp
    133     push esi
    134     push edi
    135     sub  esp, 0x40
    136     push eax
    137     mov  esi, ebp
    138     add  esi, 8
    139     mov  edi, esp
    140     add  edi, 4
    141     mov  ecx, 16
    142     rep  movsd
    143 
    144     ; call C-code
    145     call ASM_PFX(EbcInterpret)
    146     add  esp, 0x44
    147     pop  edi
    148     pop  esi
    149     pop  ebp
    150     ret
    151 
    152 ;****************************************************************************
    153 ; EbcLLExecuteEbcImageEntryPoint
    154 ;
    155 ; Begin executing an EBC image.
    156 ;****************************************************************************
    157 ; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)
    158 global ASM_PFX(EbcLLExecuteEbcImageEntryPoint)
    159 ASM_PFX(EbcLLExecuteEbcImageEntryPoint):
    160     ;
    161     ;; mov eax, 0xca112ebc
    162     ;; mov eax, EbcEntryPoint
    163     ;; mov ecx, EbcLLExecuteEbcImageEntryPoint
    164     ;; jmp ecx
    165     ;
    166     ; Caller uses above instruction to jump here
    167     ; The stack is below:
    168     ; +-----------+
    169     ; |  RetAddr  |
    170     ; +-----------+
    171     ; |EntryPoint | (EAX)
    172     ; +-----------+
    173     ; |ImageHandle|
    174     ; +-----------+
    175     ; |SystemTable|
    176     ; +-----------+
    177     ; |  RetAddr  | <- ESP is here
    178     ; +-----------+
    179     ; |ImageHandle|
    180     ; +-----------+
    181     ; |SystemTable|
    182     ; +-----------+
    183     ;
    184 
    185     ; Construct new stack
    186     mov  [esp - 0xC], eax
    187     mov  eax, [esp + 0x4]
    188     mov  [esp - 0x8], eax
    189     mov  eax, [esp + 0x8]
    190     mov  [esp - 0x4], eax
    191 
    192     ; call C-code
    193     sub  esp, 0xC
    194     call ASM_PFX(ExecuteEbcImageEntryPoint)
    195     add  esp, 0xC
    196     ret
    197 
    198