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   page    ,132
     18   title   VM ASSEMBLY LANGUAGE ROUTINES
     19 
     20 ;---------------------------------------------------------------------------
     21 ; Equate files needed.
     22 ;---------------------------------------------------------------------------
     23 
     24 .XLIST
     25 
     26 .LIST
     27 
     28 ;---------------------------------------------------------------------------
     29 ; Assembler options
     30 ;---------------------------------------------------------------------------
     31 
     32 .686p
     33 .model  flat, C
     34 .code
     35 CopyMem  PROTO  Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
     36 EbcInterpret               PROTO
     37 ExecuteEbcImageEntryPoint  PROTO
     38 
     39 ;****************************************************************************
     40 ; EbcLLCALLEXNative
     41 ;
     42 ; This function is called to execute an EBC CALLEX instruction
     43 ; to native code.
     44 ; This instruction requires that we thunk out to external native
     45 ; code. For IA32, we simply switch stacks and jump to the
     46 ; specified function. On return, we restore the stack pointer
     47 ; to its original location.
     48 ;
     49 ; Destroys no working registers.
     50 ;****************************************************************************
     51 ; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
     52 EbcLLCALLEXNative        PROC        PUBLIC
     53       push   ebp
     54       push   ebx
     55       mov    ebp, esp              ; standard function prolog
     56 
     57       ; Get function address in a register
     58       ; mov ecx, FuncAddr => mov ecx, dword ptr [FuncAddr]
     59       mov    ecx, dword ptr [esp]+0Ch
     60 
     61       ; Set stack pointer to new value
     62       ; mov eax, NewStackPointer => mov eax, dword ptr [NewSp]
     63       mov    eax, dword ptr [esp] + 14h
     64       mov    edx, dword ptr [esp] + 10h
     65       sub    eax, edx
     66       sub    esp, eax
     67       mov    ebx, esp
     68       push   ecx
     69       push   eax
     70       push   edx
     71       push   ebx
     72       call   CopyMem
     73       pop    eax
     74       pop    eax
     75       pop    eax
     76       pop    ecx
     77 
     78       ; Now call the external routine
     79       call  ecx
     80 
     81       ; ebp is preserved by the callee. In this function it
     82       ; equals the original esp, so set them equal
     83       mov    esp, ebp
     84 
     85       ; Standard function epilog
     86       mov      esp, ebp
     87       pop      ebx
     88       pop      ebp
     89       ret
     90 EbcLLCALLEXNative    ENDP
     91 
     92 ;****************************************************************************
     93 ; EbcLLEbcInterpret
     94 ;
     95 ; Begin executing an EBC image.
     96 ;****************************************************************************
     97 ; UINT64 EbcLLEbcInterpret(VOID)
     98 EbcLLEbcInterpret PROC PUBLIC
     99     ;
    100     ;; mov eax, 0xca112ebc
    101     ;; mov eax, EbcEntryPoint
    102     ;; mov ecx, EbcLLEbcInterpret
    103     ;; jmp ecx
    104     ;
    105     ; Caller uses above instruction to jump here
    106     ; The stack is below:
    107     ; +-----------+
    108     ; |  RetAddr  |
    109     ; +-----------+
    110     ; |EntryPoint | (EAX)
    111     ; +-----------+
    112     ; |   Arg1    | <- EDI
    113     ; +-----------+
    114     ; |   Arg2    |
    115     ; +-----------+
    116     ; |   ...     |
    117     ; +-----------+
    118     ; |   Arg16   |
    119     ; +-----------+
    120     ; |   EDI     |
    121     ; +-----------+
    122     ; |   ESI     |
    123     ; +-----------+
    124     ; |   EBP     | <- EBP
    125     ; +-----------+
    126     ; |  RetAddr  | <- ESP is here
    127     ; +-----------+
    128     ; |   Arg1    | <- ESI
    129     ; +-----------+
    130     ; |   Arg2    |
    131     ; +-----------+
    132     ; |   ...     |
    133     ; +-----------+
    134     ; |   Arg16   |
    135     ; +-----------+
    136     ; 
    137 
    138     ; Construct new stack
    139     push ebp
    140     mov  ebp, esp
    141     push esi
    142     push edi
    143     sub  esp, 40h
    144     push eax
    145     mov  esi, ebp
    146     add  esi, 8
    147     mov  edi, esp
    148     add  edi, 4
    149     mov  ecx, 16
    150     rep  movsd
    151     
    152     ; call C-code
    153     call EbcInterpret
    154     add  esp, 44h
    155     pop  edi
    156     pop  esi
    157     pop  ebp
    158     ret
    159 EbcLLEbcInterpret ENDP
    160 
    161 ;****************************************************************************
    162 ; EbcLLExecuteEbcImageEntryPoint
    163 ;
    164 ; Begin executing an EBC image.
    165 ;****************************************************************************
    166 ; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)
    167 EbcLLExecuteEbcImageEntryPoint PROC PUBLIC
    168     ;
    169     ;; mov eax, 0xca112ebc
    170     ;; mov eax, EbcEntryPoint
    171     ;; mov ecx, EbcLLExecuteEbcImageEntryPoint
    172     ;; jmp ecx
    173     ;
    174     ; Caller uses above instruction to jump here
    175     ; The stack is below:
    176     ; +-----------+
    177     ; |  RetAddr  |
    178     ; +-----------+
    179     ; |EntryPoint | (EAX)
    180     ; +-----------+
    181     ; |ImageHandle|
    182     ; +-----------+
    183     ; |SystemTable|
    184     ; +-----------+
    185     ; |  RetAddr  | <- ESP is here
    186     ; +-----------+
    187     ; |ImageHandle|
    188     ; +-----------+
    189     ; |SystemTable|
    190     ; +-----------+
    191     ; 
    192     
    193     ; Construct new stack
    194     mov  [esp - 0Ch], eax
    195     mov  eax, [esp + 04h]
    196     mov  [esp - 08h], eax
    197     mov  eax, [esp + 08h]
    198     mov  [esp - 04h], eax
    199     
    200     ; call C-code
    201     sub  esp, 0Ch
    202     call ExecuteEbcImageEntryPoint
    203     add  esp, 0Ch
    204     ret
    205 EbcLLExecuteEbcImageEntryPoint ENDP
    206 
    207 END
    208