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 + -
显示快捷键?