ebcexecute.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,978 行 · 第 1/5 页

C
2,978
字号
/*++

Copyright (c) 2004 - 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:

  EbcExecute.c

Abstract:

  Contains code that implements the virtual machine.

--*/

#include "Tiano.h"
#include "EfiDriverLib.h"

#include EFI_PROTOCOL_DEFINITION (Ebc)
#include EFI_PROTOCOL_DEFINITION (DebugSupport)

#include "EbcInt.h"
#include "EbcExecute.h"


//
// Define some useful data size constants to allow switch statements based on
// size of operands or data.
//
#define DATA_SIZE_INVALID 0
#define DATA_SIZE_8       1
#define DATA_SIZE_16      2
#define DATA_SIZE_32      4
#define DATA_SIZE_64      8
#define DATA_SIZE_N       48  // 4 or 8
//
// Structure we'll use to dispatch opcodes to execute functions.
//
typedef struct {
  EFI_STATUS (*ExecuteFunction) (IN VM_CONTEXT * VmPtr);
}
VM_TABLE_ENTRY;

typedef
UINT64
(*DATA_MANIP_EXEC_FUNCTION) (
  IN VM_CONTEXT * VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
INT16
VmReadIndex16 (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     CodeOffset
  );

STATIC
INT32
VmReadIndex32 (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     CodeOffset
  );

STATIC
INT64
VmReadIndex64 (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     CodeOffset
  );

STATIC
UINT8
VmReadMem8 (
  IN VM_CONTEXT *VmPtr,
  IN UINTN      Addr
  );

STATIC
UINT16
VmReadMem16 (
  IN VM_CONTEXT *VmPtr,
  IN UINTN      Addr
  );

STATIC
UINT32
VmReadMem32 (
  IN VM_CONTEXT *VmPtr,
  IN UINTN      Addr
  );

STATIC
UINT64
VmReadMem64 (
  IN VM_CONTEXT *VmPtr,
  IN UINTN      Addr
  );

STATIC
UINTN
VmReadMemN (
  IN VM_CONTEXT *VmPtr,
  IN UINTN      Addr
  );

STATIC
EFI_STATUS
VmWriteMem8 (
  IN VM_CONTEXT *VmPtr,
  UINTN         Addr,
  IN UINT8      Data
  );

STATIC
EFI_STATUS
VmWriteMem16 (
  IN VM_CONTEXT *VmPtr,
  UINTN         Addr,
  IN UINT16     Data
  );

STATIC
EFI_STATUS
VmWriteMem32 (
  IN VM_CONTEXT *VmPtr,
  UINTN         Addr,
  IN UINT32     Data
  );

EFI_STATUS
VmWriteMemN (
  IN VM_CONTEXT *VmPtr,
  UINTN         Addr,
  IN UINTN      Data
  );

EFI_STATUS
VmWriteMem64 (
  IN VM_CONTEXT *VmPtr,
  UINTN         Addr,
  IN UINT64     Data
  );

STATIC
UINT16
VmReadCode16 (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     Offset
  );

STATIC
UINT32
VmReadCode32 (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     Offset
  );

STATIC
UINT64
VmReadCode64 (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     Offset
  );

STATIC
INT8
VmReadImmed8 (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     Offset
  );

STATIC
INT16
VmReadImmed16 (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     Offset
  );

STATIC
INT32
VmReadImmed32 (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     Offset
  );

STATIC
INT64
VmReadImmed64 (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     Offset
  );

STATIC
UINTN
ConvertStackAddr (
  IN VM_CONTEXT   *VmPtr,
  IN UINTN        Addr
  );

STATIC
EFI_STATUS
ExecuteDataManip (
  IN VM_CONTEXT   *VmPtr,
  IN BOOLEAN      IsSignedOperation
  );

//
// Functions that execute VM opcodes
//
STATIC
EFI_STATUS
ExecuteBREAK (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteJMP (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteJMP8 (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteCALL (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteRET (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteCMP (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteCMPI (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteMOVxx (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteMOVI (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteMOVIn (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteMOVREL (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecutePUSHn (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecutePUSH (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecutePOPn (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecutePOP (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteSignedDataManip (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteUnsignedDataManip (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteLOADSP (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteSTORESP (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteMOVsnd (
  IN VM_CONTEXT *VmPtr
  );

STATIC
EFI_STATUS
ExecuteMOVsnw (
  IN VM_CONTEXT *VmPtr
  );

//
// Data manipulation subfunctions
//
STATIC
UINT64
ExecuteNOT (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteNEG (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteADD (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteSUB (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteMUL (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteMULU (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteDIV (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteDIVU (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteMOD (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteMODU (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteAND (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteOR (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteXOR (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteSHL (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteSHR (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteASHR (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteEXTNDB (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteEXTNDW (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

STATIC
UINT64
ExecuteEXTNDD (
  IN VM_CONTEXT *VmPtr,
  IN UINT64     Op1,
  IN UINT64     Op2
  );

//
// Once we retrieve the operands for the data manipulation instructions,
// call these functions to perform the operation.
//
static CONST DATA_MANIP_EXEC_FUNCTION mDataManipDispatchTable[] = {
  ExecuteNOT,
  ExecuteNEG,
  ExecuteADD,
  ExecuteSUB,
  ExecuteMUL,
  ExecuteMULU,
  ExecuteDIV,
  ExecuteDIVU,
  ExecuteMOD,
  ExecuteMODU,
  ExecuteAND,
  ExecuteOR,
  ExecuteXOR,
  ExecuteSHL,
  ExecuteSHR,
  ExecuteASHR,
  ExecuteEXTNDB,
  ExecuteEXTNDW,
  ExecuteEXTNDD,
};

static CONST VM_TABLE_ENTRY           mVmOpcodeTable[] = {
  ExecuteBREAK,             // opcode 0x00
  ExecuteJMP,               // opcode 0x01
  ExecuteJMP8,              // opcode 0x02
  ExecuteCALL,              // opcode 0x03
  ExecuteRET,               // opcode 0x04
  ExecuteCMP,               // opcode 0x05 CMPeq
  ExecuteCMP,               // opcode 0x06 CMPlte
  ExecuteCMP,               // opcode 0x07 CMPgte
  ExecuteCMP,               // opcode 0x08 CMPulte
  ExecuteCMP,               // opcode 0x09 CMPugte
  ExecuteUnsignedDataManip, // opcode 0x0A NOT
  ExecuteSignedDataManip,   // opcode 0x0B NEG
  ExecuteSignedDataManip,   // opcode 0x0C ADD
  ExecuteSignedDataManip,   // opcode 0x0D SUB
  ExecuteSignedDataManip,   // opcode 0x0E MUL
  ExecuteUnsignedDataManip, // opcode 0x0F MULU
  ExecuteSignedDataManip,   // opcode 0x10 DIV
  ExecuteUnsignedDataManip, // opcode 0x11 DIVU
  ExecuteSignedDataManip,   // opcode 0x12 MOD
  ExecuteUnsignedDataManip, // opcode 0x13 MODU
  ExecuteUnsignedDataManip, // opcode 0x14 AND
  ExecuteUnsignedDataManip, // opcode 0x15 OR
  ExecuteUnsignedDataManip, // opcode 0x16 XOR
  ExecuteUnsignedDataManip, // opcode 0x17 SHL
  ExecuteUnsignedDataManip, // opcode 0x18 SHR
  ExecuteSignedDataManip,   // opcode 0x19 ASHR
  ExecuteUnsignedDataManip, // opcode 0x1A EXTNDB
  ExecuteUnsignedDataManip, // opcode 0x1B EXTNDW
  ExecuteUnsignedDataManip, // opcode 0x1C EXTNDD
  ExecuteMOVxx,             // opcode 0x1D MOVBW
  ExecuteMOVxx,             // opcode 0x1E MOVWW
  ExecuteMOVxx,             // opcode 0x1F MOVDW
  ExecuteMOVxx,             // opcode 0x20 MOVQW
  ExecuteMOVxx,             // opcode 0x21 MOVBD
  ExecuteMOVxx,             // opcode 0x22 MOVWD
  ExecuteMOVxx,             // opcode 0x23 MOVDD
  ExecuteMOVxx,             // opcode 0x24 MOVQD
  ExecuteMOVsnw,            // opcode 0x25 MOVsnw
  ExecuteMOVsnd,            // opcode 0x26 MOVsnd
  NULL,                     // opcode 0x27
  ExecuteMOVxx,             // opcode 0x28 MOVqq
  ExecuteLOADSP,            // opcode 0x29 LOADSP SP1, R2
  ExecuteSTORESP,           // opcode 0x2A STORESP R1, SP2
  ExecutePUSH,              // opcode 0x2B PUSH {@}R1 [imm16]
  ExecutePOP,               // opcode 0x2C POP {@}R1 [imm16]
  ExecuteCMPI,              // opcode 0x2D CMPIEQ
  ExecuteCMPI,              // opcode 0x2E CMPILTE
  ExecuteCMPI,              // opcode 0x2F CMPIGTE
  ExecuteCMPI,              // opcode 0x30 CMPIULTE
  ExecuteCMPI,              // opcode 0x31 CMPIUGTE
  ExecuteMOVxx,             // opcode 0x32 MOVN
  ExecuteMOVxx,             // opcode 0x33 MOVND
  NULL,                     // opcode 0x34
  ExecutePUSHn,             // opcode 0x35
  ExecutePOPn,              // opcode 0x36
  ExecuteMOVI,              // opcode 0x37 - mov immediate data
  ExecuteMOVIn,             // opcode 0x38 - mov immediate natural
  ExecuteMOVREL,            // opcode 0x39 - move data relative to PC
};

//
// Length of JMP instructions, depending on upper two bits of opcode.
//
static CONST UINT8                    mJMPLen[] = { 2, 2, 6, 10 };

EFI_STATUS
EbcExecuteInstructions (
  IN EFI_EBC_VM_TEST_PROTOCOL *This,
  IN VM_CONTEXT               *VmPtr,
  IN OUT UINTN                *InstructionCount
  )

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?