Home | History | Annotate | Download | only in EbcDxe
      1 /** @file
      2   Main routines for the EBC interpreter.  Includes the initialization and
      3   main interpreter routines.
      4 
      5 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
      6 This program and the accompanying materials
      7 are licensed and made available under the terms and conditions of the BSD License
      8 which accompanies this distribution.  The full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #ifndef _EBC_INT_H_
     17 #define _EBC_INT_H_
     18 
     19 
     20 #include <Uefi.h>
     21 
     22 #include <Protocol/DebugSupport.h>
     23 #include <Protocol/Ebc.h>
     24 #include <Protocol/EbcVmTest.h>
     25 #include <Protocol/EbcSimpleDebugger.h>
     26 
     27 #include <Library/BaseLib.h>
     28 #include <Library/DebugLib.h>
     29 #include <Library/UefiDriverEntryPoint.h>
     30 #include <Library/BaseMemoryLib.h>
     31 #include <Library/UefiBootServicesTableLib.h>
     32 #include <Library/MemoryAllocationLib.h>
     33 
     34 extern VM_CONTEXT                    *mVmPtr;
     35 
     36 //
     37 // Bits of exception flags field of VM context
     38 //
     39 #define EXCEPTION_FLAG_FATAL    0x80000000  // can't continue
     40 #define EXCEPTION_FLAG_ERROR    0x40000000  // bad, but try to continue
     41 #define EXCEPTION_FLAG_WARNING  0x20000000  // harmless problem
     42 #define EXCEPTION_FLAG_NONE     0x00000000  // for normal return
     43 //
     44 // Flags passed to the internal create-thunks function.
     45 //
     46 #define FLAG_THUNK_ENTRY_POINT  0x01  // thunk for an image entry point
     47 #define FLAG_THUNK_PROTOCOL     0x00  // thunk for an EBC protocol service
     48 //
     49 // Put this value at the bottom of the VM's stack gap so we can check it on
     50 // occasion to make sure the stack has not been corrupted.
     51 //
     52 #define VM_STACK_KEY_VALUE  0xDEADBEEF
     53 
     54 /**
     55   Create thunks for an EBC image entry point, or an EBC protocol service.
     56 
     57   @param  ImageHandle           Image handle for the EBC image. If not null, then
     58                                 we're creating a thunk for an image entry point.
     59   @param  EbcEntryPoint         Address of the EBC code that the thunk is to call
     60   @param  Thunk                 Returned thunk we create here
     61   @param  Flags                 Flags indicating options for creating the thunk
     62 
     63   @retval EFI_SUCCESS           The thunk was created successfully.
     64   @retval EFI_INVALID_PARAMETER The parameter of EbcEntryPoint is not 16-bit
     65                                 aligned.
     66   @retval EFI_OUT_OF_RESOURCES  There is not enough memory to created the EBC
     67                                 Thunk.
     68   @retval EFI_BUFFER_TOO_SMALL  EBC_THUNK_SIZE is not larger enough.
     69 
     70 **/
     71 EFI_STATUS
     72 EbcCreateThunks (
     73   IN EFI_HANDLE           ImageHandle,
     74   IN VOID                 *EbcEntryPoint,
     75   OUT VOID                **Thunk,
     76   IN  UINT32              Flags
     77   );
     78 
     79 /**
     80   Add a thunk to our list of thunks for a given image handle.
     81   Also flush the instruction cache since we've written thunk code
     82   to memory that will be executed eventually.
     83 
     84   @param  ImageHandle            The image handle to which the thunk is tied.
     85   @param  ThunkBuffer            The buffer that has been created/allocated.
     86   @param  ThunkSize              The size of the thunk memory allocated.
     87 
     88   @retval EFI_OUT_OF_RESOURCES   Memory allocation failed.
     89   @retval EFI_SUCCESS            The function completed successfully.
     90 
     91 **/
     92 EFI_STATUS
     93 EbcAddImageThunk (
     94   IN EFI_HANDLE      ImageHandle,
     95   IN VOID            *ThunkBuffer,
     96   IN UINT32          ThunkSize
     97   );
     98 
     99 //
    100 // The interpreter calls these when an exception is detected,
    101 // or as a periodic callback.
    102 //
    103 /**
    104   The VM interpreter calls this function when an exception is detected.
    105 
    106   @param  ExceptionType          Specifies the processor exception detected.
    107   @param  ExceptionFlags         Specifies the exception context.
    108   @param  VmPtr                  Pointer to a VM context for passing info to the
    109                                  EFI debugger.
    110 
    111   @retval EFI_SUCCESS            This function completed successfully.
    112 
    113 **/
    114 EFI_STATUS
    115 EbcDebugSignalException (
    116   IN EFI_EXCEPTION_TYPE                   ExceptionType,
    117   IN EXCEPTION_FLAGS                      ExceptionFlags,
    118   IN VM_CONTEXT                           *VmPtr
    119   );
    120 
    121 //
    122 // Define a constant of how often to call the debugger periodic callback
    123 // function.
    124 //
    125 #define EFI_TIMER_UNIT_1MS            (1000 * 10)
    126 #define EBC_VM_PERIODIC_CALLBACK_RATE (1000 * EFI_TIMER_UNIT_1MS)
    127 #define STACK_POOL_SIZE               (1024 * 1020)
    128 #define MAX_STACK_NUM                 4
    129 
    130 //
    131 // External low level functions that are native-processor dependent
    132 //
    133 /**
    134   The VM thunk code stuffs an EBC entry point into a processor
    135   register. Since we can't use inline assembly to get it from
    136   the interpreter C code, stuff it into the return value
    137   register and return.
    138 
    139   @return  The contents of the register in which the entry point is passed.
    140 
    141 **/
    142 UINTN
    143 EFIAPI
    144 EbcLLGetEbcEntryPoint (
    145   VOID
    146   );
    147 
    148 /**
    149   This function is called to execute an EBC CALLEX instruction.
    150   This instruction requires that we thunk out to external native
    151   code. For x64, we switch stacks, copy the arguments to the stack
    152   and jump to the specified function.
    153   On return, we restore the stack pointer to its original location.
    154   Destroys no working registers.
    155 
    156   @param  CallAddr     The function address.
    157   @param  EbcSp        The new EBC stack pointer.
    158   @param  FramePtr     The frame pointer.
    159 
    160   @return The unmodified value returned by the native code.
    161 
    162 **/
    163 INT64
    164 EFIAPI
    165 EbcLLCALLEXNative (
    166   IN UINTN        CallAddr,
    167   IN UINTN        EbcSp,
    168   IN VOID         *FramePtr
    169   );
    170 
    171 /**
    172   This function is called to execute an EBC CALLEX instruction.
    173   The function check the callee's content to see whether it is common native
    174   code or a thunk to another piece of EBC code.
    175   If the callee is common native code, use EbcLLCAllEXASM to manipulate,
    176   otherwise, set the VM->IP to target EBC code directly to avoid another VM
    177   be startup which cost time and stack space.
    178 
    179   @param  VmPtr            Pointer to a VM context.
    180   @param  FuncAddr         Callee's address
    181   @param  NewStackPointer  New stack pointer after the call
    182   @param  FramePtr         New frame pointer after the call
    183   @param  Size             The size of call instruction
    184 
    185 **/
    186 VOID
    187 EbcLLCALLEX (
    188   IN VM_CONTEXT   *VmPtr,
    189   IN UINTN        FuncAddr,
    190   IN UINTN        NewStackPointer,
    191   IN VOID         *FramePtr,
    192   IN UINT8        Size
    193   );
    194 
    195 /**
    196   Returns the stack index and buffer assosicated with the Handle parameter.
    197 
    198   @param  Handle                The EFI handle as the index to the EBC stack.
    199   @param  StackBuffer           A pointer to hold the returned stack buffer.
    200   @param  BufferIndex           A pointer to hold the returned stack index.
    201 
    202   @retval EFI_OUT_OF_RESOURCES  The Handle parameter does not correspond to any
    203                                 existing EBC stack.
    204   @retval EFI_SUCCESS           The stack index and buffer were found and
    205                                 returned to the caller.
    206 
    207 **/
    208 EFI_STATUS
    209 GetEBCStack(
    210   IN  EFI_HANDLE Handle,
    211   OUT VOID       **StackBuffer,
    212   OUT UINTN      *BufferIndex
    213   );
    214 
    215 /**
    216   Returns from the EBC stack by stack Index.
    217 
    218   @param  Index        Specifies which EBC stack to return from.
    219 
    220   @retval EFI_SUCCESS  The function completed successfully.
    221 
    222 **/
    223 EFI_STATUS
    224 ReturnEBCStack(
    225   IN UINTN Index
    226   );
    227 
    228 /**
    229   Allocates memory to hold all the EBC stacks.
    230 
    231   @retval EFI_SUCCESS          The EBC stacks were allocated successfully.
    232   @retval EFI_OUT_OF_RESOURCES Not enough memory available for EBC stacks.
    233 
    234 **/
    235 EFI_STATUS
    236 InitEBCStack (
    237   VOID
    238   );
    239 
    240 /**
    241   Free all EBC stacks allocated before.
    242 
    243   @retval EFI_SUCCESS   All the EBC stacks were freed.
    244 
    245 **/
    246 EFI_STATUS
    247 FreeEBCStack(
    248   VOID
    249   );
    250 
    251 /**
    252   Returns from the EBC stack associated with the Handle parameter.
    253 
    254   @param  Handle      Specifies the EFI handle to find the EBC stack with.
    255 
    256   @retval EFI_SUCCESS The function completed successfully.
    257 
    258 **/
    259 EFI_STATUS
    260 ReturnEBCStackByHandle(
    261   IN EFI_HANDLE Handle
    262   );
    263 
    264 typedef struct {
    265   EFI_EBC_PROTOCOL  *This;
    266   VOID              *EntryPoint;
    267   EFI_HANDLE        ImageHandle;
    268   VM_CONTEXT        VmContext;
    269 } EFI_EBC_THUNK_DATA;
    270 
    271 #define EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('e', 'b', 'c', 'p')
    272 
    273 
    274 #define EBC_PROTOCOL_PRIVATE_DATA_FROM_THIS(a) \
    275       CR(a, EBC_PROTOCOL_PRIVATE_DATA, EbcProtocol, EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE)
    276 
    277 
    278 #endif // #ifndef _EBC_INT_H_
    279