/*++ BUILD Version: 0000 // Increment this if a change has global effects Copyright (c) 1994 Microsoft Corporation Module Name: emulate.h Abstract: This module contains the private header file for the x86 bios emulation. Author: David N. Cutler (davec) 2-Sep-1994 Revision History: --*/ #ifndef _EMULATE_ #define _EMULATE_ #include "setjmp.h" #include "xm86.h" #include "x86new.h" // // Define debug tracing flags. // //#define XM_DEBUG 1 // ****** temp ****** #define TRACE_INSTRUCTIONS 0x1 #define TRACE_OPERANDS 0x2 #define TRACE_GENERAL_REGISTERS 0x4 #define TRACE_OVERRIDE 0x8 #define TRACE_JUMPS 0x10 #define TRACE_SPECIFIERS 0x20 #define TRACE_SINGLE_STEP 0x40 // // Define opcode function table indexes. // // N.B. This values must correspond exactly one for one with the function // table entries. If the C language had indexed initializers this // type would not be necessary. // typedef enum _XM_FUNCTION_TABLE_INDEX { // // ASCII operators. // X86_AAA_OP, X86_AAD_OP, X86_AAM_OP, X86_AAS_OP, X86_DAA_OP, X86_DAS_OP, // // Group 1 operators. // X86_ADD_OP, X86_OR_OP, X86_ADC_OP, X86_SBB_OP, X86_AND_OP, X86_SUB_OP, X86_XOR_OP, X86_CMP_OP, // // Group 2 operators. // X86_ROL_OP, X86_ROR_OP, X86_RCL_OP, X86_RCR_OP, X86_SHL_OP, X86_SHR_OP, X86_FILL0_OP, X86_SAR_OP, // // Group 3 operators. // X86_TEST_OP, X86_FILL1_OP, X86_NOT_OP, X86_NEG_OP, X86_MUL_OP, X86_IMULX_OP, X86_DIV_OP, X86_IDIV_OP, // // Group 4 and 5 operators. // X86_INC_OP, X86_DEC_OP, X86_CALL_OP, X86_FILL2_OP, X86_JMP_OP, X86_FILL3_OP, X86_PUSH_OP, X86_FILL4_OP, // // Group 8 operators. // X86_BT_OP, X86_BTS_OP, X86_BTR_OP, X86_BTC_OP, // // Stack push and pop operators. // X86_POP_OP, X86_PUSHA_OP, X86_POPA_OP, // // Jump operators. // X86_JXX_OP, X86_LOOP_OP, X86_JCXZ_OP, // // Control operators. // X86_ENTER_OP, X86_HLT_OP, X86_INT_OP, X86_IRET_OP, X86_LEAVE_OP, X86_RET_OP, // // Set boolean byte value based on condition. // X86_SXX_OP, // // Condition code operators. // X86_CMC_OP, X86_CLC_OP, X86_STC_OP, X86_CLI_OP, X86_STI_OP, X86_CLD_OP, X86_STD_OP, X86_LAHF_OP, X86_SAHF_OP, // // General move operators. // X86_MOV_OP, X86_XCHG_OP, // // Convert operations. // X86_CBW_OP, X86_CWD_OP, // // Single multiply operator. // X86_IMUL_OP, // // String operators. // X86_CMPS_OP, X86_INS_OP, X86_LODS_OP, X86_MOVS_OP, X86_OUTS_OP, X86_SCAS_OP, X86_STOS_OP, // // Effective address operators. // X86_BOUND_OP, X86_LEA_OP, // // Double shift operators. // X86_SHLD_OP, X86_SHRD_OP, // // I/O operators. // X86_IN_OP, X86_OUT_OP, // // Bit scan operators. // X86_BSF_OP, X86_BSR_OP, // // Byte swap operators. // X86_BSWAP_OP, // // Add/compare and exchange operators. // X86_XADD_OP, X86_CMPXCHG_OP, // // No operation. // X86_NOP_OP, // // Illegal opcode. // X86_ILL_OP, X86_MAXIMUM_INDEX } XM_FUNCTION_TABLE_INDEX; // // Define 8-bit register numbers. // typedef enum _X86_8BIT_REGISTER { AL, CL, DL, BL, AH, CH, DH, BH } X86_8BIT_REGISTER; // // Define 16-bit register numbers. // typedef enum _X86_16BIT_REGISTER { AX, CX, DX, BX, SP, BP, SI, DI } X86_16BIT_REGISTER; // // Define 32-bit register numbers. // typedef enum _X86_32BIT_REGISTER { EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI } X86_32BIT_REGISTER; // // Define general register structure. // typedef union _X86_GENERAL_REGISTER { ULONG Exx; union { USHORT Xx; struct { UCHAR Xl; UCHAR Xh; }; }; } X86_GENERAL_REGISTER, *PX86_GENERAL_REGISTER; // // Define segment register numbers. // typedef enum _X86_SEGMENT_REGISTER { ES, CS, SS, DS, FS, GS } X86_SEGMENT_REGISTER; // // Define instruction format types. // typedef enum _XM_FORMAT_TYPE { // // N.B. These format codes MUST be the first codes and MUST be // exactly in this order since the ordering corresponds to // segment numbers. // FormatSegmentES, FormatSegmentCS, FormatSegmentSS, FormatSegmentDS, FormatSegmentFS, FormatSegmentGS, // // N.B. These format codes MUST be the second codes and MUST be // exactly in this order since the ordering corresponds to // biased segment number. The entry for the code segment is // a dummy entry to make the indexing work right. // FormatLoadSegmentES, FormatLoadSegmentCS, FormatLoadSegmentSS, FormatLoadSegmentDS, FormatLoadSegmentFS, FormatLoadSegmentGS, // // The following codes can be in any order. // FormatGroup1General, FormatGroup1Immediate, FormatGroup2By1, FormatGroup2ByCL, FormatGroup2ByByte, FormatGroup3General, FormatGroup4General, FormatGroup5General, FormatGroup8BitOffset, FormatOpcodeRegister, FormatLongJump, FormatShortJump, FormatSetccByte, FormatAccumImmediate, FormatAccumRegister, FormatMoveGeneral, FormatMoveImmediate, FormatMoveRegImmediate, FormatSegmentOffset, FormatMoveSegment, FormatMoveXxGeneral, FormatFlagsRegister, FormatPushImmediate, FormatPopGeneral, FormatImulImmediate, FormatStringOperands, FormatEffectiveOffset, FormatImmediateJump, FormatImmediateEnter, FormatGeneralBitOffset, FormatShiftDouble, FormatPortImmediate, FormatPortDX, FormatBitScanGeneral, FormatByteImmediate, FormatXlatOpcode, FormatGeneralRegister, FormatNoOperands, FormatOpcodeEscape, FormatPrefixOpcode } XM_FORMAT_TYPE; // // Defined opcode modifier bit masks. // #define WIDTH_BIT 0x1 // operand size control #define DIRECTION_BIT 0x2 // direction of operation #define SIGN_BIT 0x2 // sign extended byte // // Define prefix opcode function index values. // typedef enum _XM_PREFIX_FUNCTION_INDEX { X86_ES_OP = ES, X86_CS_OP = CS, X86_SS_OP = SS, X86_DS_OP = DS, X86_FS_OP = FS, X86_GS_OP = GS, X86_LOCK_OP, X86_ADSZ_OP, X86_OPSZ_OP, X86_REPZ_OP, X86_REPNZ_OP } XM_PREFIX_FUNCTION_INDEX; // // Define two byte opcode escape. // #define TWO_BYTE_ESCAPE 0x0f // // Define opcode control table structure. // // This table controls the decoding of instructions and there operands. // typedef struct _OPCODE_CONTROL { UCHAR FunctionIndex; UCHAR FormatType; } OPCODE_CONTROL, *POPCODE_CONTROL; // // Define emulator context structure. // // This structure holds the global emulator state. // typedef struct _XM_CONTEXT { // // Pointers to the opcode control table and the opcode name table. // POPCODE_CONTROL OpcodeControlTable; PCHAR *OpcodeNameTable; // // x86 extended flags register. // union { UCHAR AhFlags; USHORT Flags; ULONG AllFlags; struct { ULONG CF : 1; ULONG MBO : 1; ULONG PF : 1; ULONG SBZ0 : 1; ULONG AF : 1; ULONG SBZ1 : 1; ULONG ZF : 1; ULONG SF : 1; ULONG TF : 1; ULONG IF : 1; ULONG DF : 1; ULONG OF : 1; ULONG IOPL : 2; ULONG NT : 1; ULONG SBZ2 : 1; ULONG RF : 1; ULONG VM : 1; ULONG AC : 1; ULONG SBZ3 : 13; } Eflags; }; // // x86 instruction pointer. // union { USHORT Ip; ULONG Eip; }; // // x86 general registers. // X86_GENERAL_REGISTER Gpr[8]; // // x86 segment registers. // USHORT SegmentRegister[6]; // // Emulator segment descriptors. // USHORT SegmentLimit[6]; // // Instruction opcode control information read from the opcode // control table. // OPCODE_CONTROL OpcodeControl; // // Call or jmp destination segment segment. // USHORT DstSegment; // // Source and destination address and value. // union { UCHAR UNALIGNED *DstByte; USHORT UNALIGNED *DstWord; ULONG UNALIGNED *DstLong; }; union { UCHAR UNALIGNED *SrcByte; USHORT UNALIGNED *SrcWord; ULONG UNALIGNED *SrcLong; }; union { UCHAR Byte; ULONG Long; USHORT Word; } DstValue; union { UCHAR Byte; ULONG Long; USHORT Word; } SrcValue; // // Current opcode, data segment register to be used to access // data operands, function index, and operand data type, and // effective address offset. // ULONG CurrentOpcode; ULONG DataSegment; ULONG DataType; ULONG FunctionIndex; ULONG Offset; // // Prefix control information. // BOOLEAN LockPrefixActive; BOOLEAN OpaddrPrefixActive; BOOLEAN OpsizePrefixActive; BOOLEAN RepeatPrefixActive; BOOLEAN SegmentPrefixActive; UCHAR RepeatZflag; // // Effective address computation control. // BOOLEAN RegisterOffsetAddress; BOOLEAN ComputeOffsetAddress; // // Shift count. // UCHAR Shift; // // Jump buffer. // _JBTYPE JumpBuffer[_JBLEN]; // // Address of read I/O space, write I/O space, and translation address // routines. // PXM_READ_IO_SPACE ReadIoSpace; PXM_WRITE_IO_SPACE WriteIoSpace; PXM_TRANSLATE_ADDRESS TranslateAddress; } XM_CONTEXT, *PXM_CONTEXT, *RESTRICTED_POINTER PRXM_CONTEXT; // // Define opcode function and decode operand types. // typedef ULONG (*POPERAND_DECODE) ( IN PRXM_CONTEXT P ); typedef VOID (*POPCODE_FUNCTION) ( IN PRXM_CONTEXT P ); // // Operand decode prototypes. // ULONG XmPushPopSegment ( IN PRXM_CONTEXT P ); ULONG XmLoadSegment ( IN PRXM_CONTEXT P ); ULONG XmGroup1General ( IN PRXM_CONTEXT P ); ULONG XmGroup1Immediate ( IN PRXM_CONTEXT P ); ULONG XmGroup2By1 ( IN PRXM_CONTEXT P ); ULONG XmGroup2ByCL ( IN PRXM_CONTEXT P ); ULONG XmGroup2ByByte ( IN PRXM_CONTEXT P ); ULONG XmGroup3General ( IN PRXM_CONTEXT P ); ULONG XmGroup45General ( IN PRXM_CONTEXT P ); ULONG XmGroup8BitOffset ( IN PRXM_CONTEXT P ); ULONG XmOpcodeRegister ( IN PRXM_CONTEXT P ); ULONG XmLongJump ( IN PRXM_CONTEXT P ); ULONG XmShortJump ( IN PRXM_CONTEXT P ); ULONG XmSetccByte ( IN PRXM_CONTEXT P ); ULONG XmAccumImmediate ( IN PRXM_CONTEXT P ); ULONG XmAccumRegister ( IN PRXM_CONTEXT P ); ULONG XmMoveGeneral ( IN PRXM_CONTEXT P ); ULONG XmMoveImmediate ( IN PRXM_CONTEXT P ); ULONG XmMoveRegImmediate ( IN PRXM_CONTEXT P ); ULONG XmSegmentOffset ( IN PRXM_CONTEXT P ); ULONG XmMoveSegment ( IN PRXM_CONTEXT P ); ULONG XmMoveXxGeneral ( IN PRXM_CONTEXT P ); ULONG XmFlagsRegister ( IN PRXM_CONTEXT P ); ULONG XmPushImmediate ( IN PRXM_CONTEXT P ); ULONG XmPopGeneral ( IN PRXM_CONTEXT P ); ULONG XmImulImmediate ( IN PRXM_CONTEXT P ); ULONG XmStringOperands ( IN PRXM_CONTEXT P ); ULONG XmEffectiveOffset ( IN PRXM_CONTEXT P ); ULONG XmImmediateJump ( IN PRXM_CONTEXT P ); ULONG XmImmediateEnter ( IN PRXM_CONTEXT P ); ULONG XmGeneralBitOffset ( IN PRXM_CONTEXT P ); ULONG XmShiftDouble ( IN PRXM_CONTEXT P ); ULONG XmPortImmediate ( IN PRXM_CONTEXT P ); ULONG XmPortDX ( IN PRXM_CONTEXT P ); ULONG XmBitScanGeneral ( IN PRXM_CONTEXT P ); ULONG XmByteImmediate ( IN PRXM_CONTEXT P ); ULONG XmXlatOpcode ( IN PRXM_CONTEXT P ); ULONG XmGeneralRegister ( IN PRXM_CONTEXT P ); ULONG XmOpcodeEscape ( IN PRXM_CONTEXT P ); ULONG XmPrefixOpcode ( IN PRXM_CONTEXT P ); ULONG XmNoOperands ( IN PRXM_CONTEXT P ); // // Define miscellaneous prototypes. // ULONG XmComputeParity ( IN ULONG Result ); XM_STATUS XmEmulateStream ( IN PRXM_CONTEXT P, USHORT Segment, USHORT Offset, PXM86_CONTEXT Context ); UCHAR XmGetCodeByte ( IN PRXM_CONTEXT P ); UCHAR XmGetByteImmediate ( IN PRXM_CONTEXT P ); USHORT XmGetByteImmediateToWord ( IN PRXM_CONTEXT P ); ULONG XmGetByteImmediateToLong ( IN PRXM_CONTEXT P ); USHORT XmGetSignedByteImmediateToWord ( IN PRXM_CONTEXT P ); ULONG XmGetSignedByteImmediateToLong ( IN PRXM_CONTEXT P ); USHORT XmGetWordImmediate ( IN PRXM_CONTEXT P ); ULONG XmGetLongImmediate ( IN PRXM_CONTEXT P ); ULONG XmPopStack ( IN PRXM_CONTEXT P ); VOID XmPushStack ( IN PRXM_CONTEXT P, IN ULONG Value ); VOID XmSetDataType ( IN PRXM_CONTEXT P ); VOID XmStoreResult ( IN PRXM_CONTEXT P, IN ULONG Result ); // // Define operand specifier prototypes. // PVOID XmEvaluateAddressSpecifier ( IN PRXM_CONTEXT P, OUT PLONG Register ); PVOID XmGetOffsetAddress ( IN PRXM_CONTEXT P, IN ULONG Offset ); PVOID XmGetRegisterAddress ( IN PRXM_CONTEXT P, IN ULONG Number ); PVOID XmGetStringAddress ( IN PRXM_CONTEXT P, IN ULONG Segment, IN ULONG Register ); VOID XmSetDestinationValue ( IN PRXM_CONTEXT P, IN PVOID Destination ); VOID XmSetSourceValue ( IN PRXM_CONTEXT P, IN PVOID Source ); ULONG XmGetImmediateSourceValue ( IN PRXM_CONTEXT P, IN ULONG ByteFlag ); VOID XmSetImmediateSourceValue ( IN PRXM_CONTEXT P, IN ULONG Source ); // // ASCII operators. // VOID XmAaaOp ( IN PRXM_CONTEXT P ); VOID XmAadOp ( IN PRXM_CONTEXT P ); VOID XmAamOp ( IN PRXM_CONTEXT P ); VOID XmAasOp ( IN PRXM_CONTEXT P ); VOID XmDaaOp ( IN PRXM_CONTEXT P ); VOID XmDasOp ( IN PRXM_CONTEXT P ); // // Group 1 operations. // VOID XmAddOp ( IN PRXM_CONTEXT P ); VOID XmOrOp ( IN PRXM_CONTEXT P ); VOID XmAdcOp ( IN PRXM_CONTEXT P ); VOID XmSbbOp ( IN PRXM_CONTEXT P ); VOID XmAndOp ( IN PRXM_CONTEXT P ); VOID XmSubOp ( IN PRXM_CONTEXT P ); VOID XmXorOp ( IN PRXM_CONTEXT P ); VOID XmCmpOp ( IN PRXM_CONTEXT P ); // // Group 2 operations. // VOID XmRolOp ( IN PRXM_CONTEXT P ); VOID XmRorOp ( IN PRXM_CONTEXT P ); VOID XmRclOp ( IN PRXM_CONTEXT P ); VOID XmRcrOp ( IN PRXM_CONTEXT P ); VOID XmShlOp ( IN PRXM_CONTEXT P ); VOID XmShrOp ( IN PRXM_CONTEXT P ); VOID XmSarOp ( IN PRXM_CONTEXT P ); // // Group 3 operations. // VOID XmTestOp ( IN PRXM_CONTEXT P ); VOID XmNotOp ( IN PRXM_CONTEXT P ); VOID XmNegOp ( IN PRXM_CONTEXT P ); VOID XmDivOp ( IN PRXM_CONTEXT P ); VOID XmIdivOp ( IN PRXM_CONTEXT P ); VOID XmImulOp ( IN PRXM_CONTEXT P ); VOID XmImulxOp ( IN PRXM_CONTEXT P ); VOID XmMulOp ( IN PRXM_CONTEXT P ); // // Group 4 and 5 operators. // VOID XmIncOp ( IN PRXM_CONTEXT P ); VOID XmDecOp ( IN PRXM_CONTEXT P ); VOID XmCallOp ( PRXM_CONTEXT P ); VOID XmJmpOp ( IN PRXM_CONTEXT P ); VOID XmPushOp ( IN PRXM_CONTEXT P ); // // Group 8 operators. // VOID XmBtOp ( IN PRXM_CONTEXT P ); VOID XmBtsOp ( IN PRXM_CONTEXT P ); VOID XmBtrOp ( IN PRXM_CONTEXT P ); VOID XmBtcOp ( IN PRXM_CONTEXT P ); // // Stack operations. // VOID XmPopOp ( IN PRXM_CONTEXT P ); VOID XmPushaOp ( IN PRXM_CONTEXT P ); VOID XmPopaOp ( IN PRXM_CONTEXT P ); // // Conditional jump and set conditional operations. // VOID XmJxxOp ( IN PRXM_CONTEXT P ); VOID XmLoopOp ( IN PRXM_CONTEXT P ); VOID XmJcxzOp ( IN PRXM_CONTEXT P ); VOID XmSxxOp ( IN PRXM_CONTEXT P ); // // Condition code operations. // VOID XmClcOp ( PRXM_CONTEXT P ); VOID XmCldOp ( PRXM_CONTEXT P ); VOID XmCliOp ( PRXM_CONTEXT P ); VOID XmCmcOp ( PRXM_CONTEXT P ); VOID XmStcOp ( PRXM_CONTEXT P ); VOID XmStdOp ( PRXM_CONTEXT P ); VOID XmStiOp ( PRXM_CONTEXT P ); VOID XmLahfOp ( PRXM_CONTEXT P ); VOID XmSahfOp ( PRXM_CONTEXT P ); // // Move operations. // VOID XmMovOp ( PRXM_CONTEXT P ); VOID XmXchgOp ( PRXM_CONTEXT P ); // // Convert operations. // VOID XmCbwOp ( PRXM_CONTEXT P ); VOID XmCwdOp ( PRXM_CONTEXT P ); // // Control operations. // VOID XmEnterOp ( PRXM_CONTEXT P ); VOID XmHltOp ( PRXM_CONTEXT P ); VOID XmIntOp ( PRXM_CONTEXT P ); VOID XmIretOp ( PRXM_CONTEXT P ); VOID XmLeaveOp ( PRXM_CONTEXT P ); VOID XmRetOp ( PRXM_CONTEXT P ); // // String operations. // VOID XmCmpsOp ( PRXM_CONTEXT P ); VOID XmInsOp ( PRXM_CONTEXT P ); VOID XmLodsOp ( PRXM_CONTEXT P ); VOID XmMovsOp ( PRXM_CONTEXT P ); VOID XmOutsOp ( PRXM_CONTEXT P ); VOID XmScasOp ( PRXM_CONTEXT P ); VOID XmStosOp ( PRXM_CONTEXT P ); // // Shift double operators. // VOID XmShldOp ( PRXM_CONTEXT P ); VOID XmShrdOp ( PRXM_CONTEXT P ); // // I/O operators. // VOID XmInOp ( PRXM_CONTEXT P ); VOID XmOutOp ( PRXM_CONTEXT P ); // // Bit scan operators. // VOID XmBsfOp ( PRXM_CONTEXT P ); VOID XmBsrOp ( PRXM_CONTEXT P ); // // MIscellaneous operations. // VOID XmXaddOp ( PRXM_CONTEXT P ); VOID XmBoundOp ( PRXM_CONTEXT P ); VOID XmBswapOp ( PRXM_CONTEXT P ); VOID XmCmpxchgOp ( PRXM_CONTEXT P ); VOID XmIllOp ( PRXM_CONTEXT P ); VOID XmNopOp ( PRXM_CONTEXT P ); // // PCI Bios emulation routines. // #if !defined(_PURE_EMULATION_) BOOLEAN XmExecuteInt1a ( IN OUT PRXM_CONTEXT Context ); VOID XmInt1aPciBiosPresent( IN OUT PRXM_CONTEXT Context ); VOID XmInt1aFindPciClassCode( IN OUT PRXM_CONTEXT Context ); VOID XmInt1aFindPciDevice( IN OUT PRXM_CONTEXT Context ); VOID XmInt1aGenerateSpecialCycle( IN OUT PRXM_CONTEXT Context ); VOID XmInt1aGetRoutingOptions( IN OUT PRXM_CONTEXT Context ); VOID XmInt1aSetPciIrq( IN OUT PRXM_CONTEXT Context ); VOID XmInt1aReadConfigRegister( IN OUT PRXM_CONTEXT Context ); VOID XmInt1aWriteConfigRegister( IN OUT PRXM_CONTEXT Context ); #endif // // Debug routines. // #if XM_DEBUG #include "stdio.h" //#define DEBUG_PRINT(_X_) DbgPrint _X_ #define DEBUG_PRINT(_X_) printf _X_ VOID XmTraceDestination ( IN PRXM_CONTEXT P, IN ULONG Destination ); VOID XmTraceFlags ( IN PRXM_CONTEXT P ); VOID XmTraceInstruction ( IN XM_OPERATION_DATATYPE DataType, IN ULONG Instruction ); VOID XmTraceJumps ( IN PRXM_CONTEXT P ); VOID XmTraceOverride ( IN PRXM_CONTEXT P ); VOID XmTraceRegisters ( IN PRXM_CONTEXT P ); VOID XmTraceResult ( IN PRXM_CONTEXT P, IN ULONG Result ); VOID XmTraceSpecifier ( IN UCHAR Specifier ); VOID XmTraceSource ( IN PRXM_CONTEXT P, IN ULONG Source ); #else #define XmTraceDestination(P, Destination) #define XmTraceInstruction(DataType, Instruction) #define XmTraceFlags(P) #define XmTraceJumps(P) #define XmTraceOverride(P) #define XmTraceRegisters(P) #define XmTraceResult(P, Result) #define XmTraceSpecifier(Specifier) #define XmTraceSource(P, Source) #endif // // Define global data. // extern XM_CONTEXT XmContext; extern BOOLEAN XmEmulatorInitialized; extern OPCODE_CONTROL XmOpcodeControlTable1[]; extern OPCODE_CONTROL XmOpcodeControlTable2[]; extern POPCODE_FUNCTION XmOpcodeFunctionTable[]; POPERAND_DECODE XmOperandDecodeTable[]; #if !defined(_PURE_EMULATION) extern UCHAR XmNumberPciBusses; extern BOOLEAN XmPciBiosPresent; extern PGETSETPCIBUSDATA XmGetPciData; extern PGETSETPCIBUSDATA XmSetPciData; #endif #if XM_DEBUG extern ULONG XmDebugFlags; extern PCHAR XmOpcodeNameTable1[]; extern PCHAR XmOpcodeNameTable2[]; #endif #endif // _EMULATE_