/*static char *SCCSID = "@(#)mi.h       6.2 92/01/28";*/
/*
 *      Machine instruction, flag definitions and character types
 *
 *   (c) Copyright IBM Corp. 1992, 1999
 *
 *   The source code for this program is not published or otherwise divested
 *   of its tradesecrets, irrespective of what has been deposited with the
 *   U.S. Copyright Office.
 */

/* NOINC */
#if __IBMC__ || __IBMCPP__
   #pragma info( none )
      #ifndef __CHKHDR__
         #pragma info( none )
      #endif
   #pragma info( restore )
#endif
/* INC */

#ifndef __MI__
#define __MI__


/*      386 eflags definitions
*/
#define F_ID            0x00200000      // CPU ID instruction supported
#define F_VIP           0x00100000      // (V)irtual (I)nterrupt (P)ending
#define F_VIF           0x00080000      // (V)irtual (I)nterrupt (F)lag
#define F_AC            0x00040000      /* (A)lignment (C)heck   */
#define F_VM            0x00020000      /* (V)irtual 8086 (M)ode */
#define F_RF            0x00010000      /* (R)esume (F)lag       */
#define F_NT            0x00004000      /* (N)ested (T)ask       */
#define F_NTCLEAR       (~F_NT)
#define F_IOPL0         0
#define F_IOPL1         0x00001000
#define F_IOPL2         0x00002000
#define F_IOPL3         0x00003000
#define F_IOPLMASK      0x00003000      /* (I)/(O) (P)rivilege (L)evel */
#define F_IOPLSYS       F_IOPL3         /* wide open                   */
#define F_IOPLclear     (~F_IOPLMASK)
#define F_OVERFLOW      0x00000800
#define F_DIRECTION     0x00000400
#define F_INTERRUPT     0x00000200
#define F_TRACE         0x00000100
#define F_SIGN          0x00000080
#define F_ZERO          0x00000040
#define F_AUX           0x00000010
#define F_PARITY        0x00000004
#define F_CARRY         0x00000001
#define F_UNDEFINED     0x0000802A

/*      CR0 (Machine Status Register) bits
*/
#define CR0_PE          0x00000001      /* (P)rotect (E)nable                   */
#define CR0_MP          0x00000002      /* (M)onitor (P)rocessor extension      */
#define CR0_EM          0x00000004      /* (EM)ulate processor extension        */
#define CR0_TS          0x00000008      /* (T)ask (thread) (S)witched           */
#define CR0_ET          0x00000010      /* (E)xtension (T)ype, 0/1=287/387      */
#define CR0_NE          0x00000020      /* (N)umeric (E)xception 0/1=use 2/10h  */
#define CR0_WP          0x00010000      /* (W)rite (P)rotect in rings 0-2       */
#define CR0_AM          0x00040000      /* (A)lignment (M)ask, enable EFlags.AC */
#define CR0_NW          0x20000000      /* (N)o (W)rite-through cache           */
#define CR0_CD          0x40000000      /* (C)ache (D)isable                    */
#define CR0_PG          0x80000000      /* (P)a(G)ing enable                    */
#define CR0_RESERVED    0x1ffaffc0      /* reserved bits                        */

/*
 *      Cache Operating Modes:
 *
 *      CR0_CD CR0_NW   Cache Fills     Write-Throughs and Invalidates
 *      ------ ------   -----------     ------------------------------
 *         1      1      disabled               disabled
 *         1      0      disabled               enabled
 *         0      1      INVALID combination - CR0 load causes GP fault
 *         0      0      enabled                enabled (Normal mode)
 */

/*      Machine Status Word bits (obsolete)
*/
#define MSW_PE          CR0_PE
#define MSW_MP          CR0_MP
#define MSW_EM          CR0_EM
#define MSW_TS          CR0_TS
#define MSW_ET          CR0_ET

// Pentium Feature Flags                                // 148688
#define VME_SUPPORTED   0x02                    // 148688
#define  DE_SUPPORTED   0x04                    // 148688

/*      CR3 (Page Directory Base Register) bits
*/
#define CR3_WRITETHROUGH 0x00000008     /* write-through cache (486 ignores)    */
#define CR3_CACHEDISABLE 0x00000010     /* cache disable                        */
#define CR3_FRAME        0xfffff000     /* page directory physical frame number */
#define CR3_RESERVED     0x00000fe7     /* reserved bits                        */

//      CR4 bits
#define CR4_VME          0x00000001
#define CR4_PVI          0x00000002
#define CR4_DE   0x00000008                     // 148688
#define CR4_OSFXSR       0x00000200             //PCR1501
#define CR4_OSXMMEXCPT   0x00000400             //PCR1501

/*      Debug Registers
*/
#define DR_COUNT        0x4             /* number of debug registers

/*      DR6 (Debug Registers Status Register) bits
*/
#define DR6_B0          0x00000001      /* breakpoint register 0 triggered */
#define DR6_B1          0x00000002      /* breakpoint register 1 triggered */
#define DR6_B2          0x00000004      /* breakpoint register 2 triggered */
#define DR6_B3          0x00000008      /* breakpoint register 3 triggered */
#define DR6_BD          0x00002000      /* ICE hardware active             */
#define DR6_BS_BIT_INDEX       0xe      /* Single step trap                */
#define DR6_BS          (1 << DR6_BS_BIT_INDEX)
#define DR6_BT          0x00008000      /* TSS trap                        */

#define DR6_VALID       (DR6_B0|DR6_B1|DR6_B2|DR6_B3|DR6_BD|DR6_BS|DR6_BT)
#define DR6_RESERVED    ~(DR6_VALID)

/*      DR7 (Debug Register Control Register) bits
*/
#define DR7_L0          0x00000001      /* DR0 Local Enable  */
#define DR7_G0          0x00000002      /* DR0 Global Enable */
#define DR7_L1          0x00000004      /* DR1 Local Enable  */
#define DR7_G1          0x00000008      /* DR1 Global Enable */
#define DR7_L2          0x00000010      /* DR2 Local Enable  */
#define DR7_G2          0x00000020      /* DR2 Global Enable */
#define DR7_L3          0x00000040      /* DR3 Local Enable  */
#define DR7_G3          0x00000080      /* DR3 Global Enable */

#define DR7_LE          0x00000100      /* Local  - Exact Match */
#define DR7_GE          0x00000200      /* Global - Exact Match */

#define DR7_RW0         0x00030000      /* DR0 RW bits  */
#define DR7_LEN0        0x000c0000      /* DR0 Len bits */
#define DR7_RW1         0x00300000      /* DR1 RW bits  */
#define DR7_LEN1        0x00c00000      /* DR1 Len bits */
#define DR7_RW2         0x03000000      /* DR2 RW bits  */
#define DR7_LEN2        0x0c000000      /* DR2 Len bits */
#define DR7_RW3         0x30000000      /* DR3 RW bits  */
#define DR7_LEN3        0xc0000000      /* DR3 Len bits */

#define DR7_RESERVED    0x0000fc00      /* DR7 Intel Reserved */

#define DR7_EXECUTE     0x0             /* Execute              */
#define DR7_WRITE       0x1             /* Data Write           */
#define DR7_IO          0x2             /* 148688 - I/O Read or Write   */
#define DR7_READWRITE   0x3             /* Data Read or Write   */

#define DR7_LEN_1       0x0             /* Length 1 bits        */
#define DR7_LEN_2       0x1             /* Length 2             */
#define DR7_LEN_4       0x3             /* Length 4             */

/*      Machine instruction, flag definitions and character types
*/
#define MI_ARPL         0x63            /* ARPL instruction             */
#define MI_HLT          0xf4            /* HLT instruction              */
#define MI_OPERANDSIZE  0x66            /* Operand size override prefix */
#define MI_ADDRESSSIZE  0x67            /* Address size override prefix */
#define MI_TWOBYTEOP    0x0f            /* Two byte opcode prefix       */

#define MI_POP_DS       0x1f
#define MI_POP_ES       0x07
#define MI_POP_FS       0xA1            /* second byte to 0Fh opcode    */
#define MI_POP_GS       0xA9            /* second byte to 0Fh opcode    */

#define MI_INT3         0xCC
#define MI_INT          0xCD
#define MI_IRET         0xCF
#define MI_LONG_JMP     0xEA
#define MI_LONG_CALL    0x9A
#define MI_LONG_RET     0xCB
#define MI_LONG_RETn    0xCA
#define MI_NEAR_RET     0xC3

#define MI_IN_PORT_AL   0xE4            /* Opcode of IN port,AL  */
#define MI_IN_PORT_AX   0xE5            /* Opcode of IN port,AX  */
#define MI_OUT_PORT_AL  0xE6            /* Opcode of OUT port,AL */
#define MI_OUT_PORT_AX  0xE7            /* Opcode of OUT port,AX */
#define MI_IN_DX_AL     0xEC            /* Opcode of IN DX,AL    */
#define MI_IN_DX_AX     0xED            /* Opcode of IN DX,AX    */
#define MI_OUT_DX_AL    0xEE            /* Opcode of OUT DX,AL   */
#define MI_OUT_DX_AX    0xEF            /* Opcode of OUT DX,AX   */

#define MI_GROUP5       0xFF            /* 5th group of 11-bit opcode inst.s */
#define MI_SEGES        0x26            /* ES override prefix */
#define MI_SEGCS        0x2E            /* CS override prefix */
#define MI_SEGSS        0x36            /* SS override prefix */
#define MI_SEGDS        0x3E            /* DS override prefix */
#define MI_SEGFS        0x64            /* FS override prefix */
#define MI_SEGGS        0x65            /* GS override prefix */

/*      ESC opcode prefix and mask
*/
#define MI_ESCMASK      0xF8
#define MI_ESC          0xD8

/*      MOD field equates
*/
#define MI_MODMASK      0xC0            /* MOD field mask                       */
#define MI_MODSHIFT     6               /* MOD field shift                      */
#define MI_MODNONE      0x00            /* MOD = 0 (no displacement)            */
#define MI_MODBYTE      0x40            /* MOD = 1 (byte displacement)          */
#define MI_MODWORD      0x80            /* MOD = 2 (word displacement)          */
#define MI_MODREG       0xC0            /* MOD = 3 (R/M field selects register) */

/*      REG field equates
*/
#define MI_REGMASK      0x38            /* REG field mask    */
#define MI_REGSHIFT     3               /* REG field shift   */
#define MI_REGAX        0x00            /* REG = 0 (AX/AL)   */
#define MI_REGCX        0x08            /* REG = 1 (CX/CL)   */
#define MI_REGDX        0x10            /* REG = 2 (DX/DL)   */
#define MI_REGBX        0x18            /* REG = 3 (BX/BL)   */
#define MI_REG3         0x18            /* REG = 3 (part of 11-bit opcode) */
#define MI_REGSP        0x20            /* REG = 4 (SP/AH)   */
#define MI_REGBP        0x28            /* REG = 5 (BP/CH)   */
#define MI_REGSI        0x30            /* REG = 6 (SI/DH)   */
#define MI_REGDI        0x38            /* REG = 7 (DI/BH)   */

#define MI_REGES        0x00            /* REG = 0  MOV seg,r/m or MOV r/m,seg */
#define MI_REGCS        0x08            /* REG = 1           */
#define MI_REGSS        0x10            /* REG = 2           */
#define MI_REGDS        0x18            /* REG = 3           */
#define MI_REGFS        0x20            /* REG = 4           */
#define MI_REGGS        0x28            /* REG = 5           */

/*      R/M field equates for memory operands (for 16-bit instructions)
*/
#define MI_RMMASK       0x07            /* R/M field mask    */
#define MI_RMSHIFT      0               /* R/M field shift   */
#define MI_RMBXSI       0x00            /* R/M = 0 ([BX+SI]) */
#define MI_RMBXDI       0x01            /* R/M = 1 ([BX+DI]) */
#define MI_RMBPSI       0x02            /* R/M = 2 ([BP+SI]) */
#define MI_RMBPDI       0x03            /* R/M = 3 ([BP+DI]) */
#define MI_RMSI         0x04            /* R/M = 4 ([SI])    */
#define MI_RMDI         0x05            /* R/M = 5 ([DI])    */
#define MI_RMBP         0x06            /* R/M = 6 ([BP])    */
#define MI_RMBX         0x07            /* R/M = 7 ([BX])    */

/*      32 bit instruction equates
*/
#define MI_SIB_SSMASK           0xc0
#define MI_SIB_SSSHIFT          0x06

#define MI_SIB_INDEXMASK        0x38
#define MI_SIB_INDEXSHIFT       0x03
#define MI_SIB_INDEXNONE        0x20

#define MI_SIB_BASEMASK         0x07
#define MI_SIB_BASESHIFT        0x00
#define MI_SIB_BASEESP          0x04
#define MI_SIB_BASENONE         0x05

#define MI_RMEDX                0x02
#define MI_RMSIB                0x04
#define MI_RMDISP               0x05
#define MI_RMEBP                0x05

#define MI_REG6                 0x30
#define MI_REGCR0               0x00

/*      following machine instructions are used in Enable_386_Specific_code
**      in virtmgr.asm
*/
#define MI_PUSH_AX              0x50    /* "push ax" instruction                */
#define MI_PUSH_IMM             0x68    /* "push immediate 16/32" instruction   */
#define MI_MOV_REG_IMM          0xB8    /* opcode for "mov reg,immediate" instr */
#define MI_MOV_REG_IMMEDIATE    0xB8    /* opcode for "mov reg,immediate" instr */
#define MI_MOV_REG_REGMEM       0x8B    /* opcode for "mov reg,r/m 16/32" instr */

/*      Miscellaneous Opcodes
*/
#define MI_ADD_AX_IMM           0x05    /* Opcode for Add (E)AX,imm(32)16       */
#define MI_CALL_NEAR_REL        0xE8    /* Opcode for Call NEAR (relative)      */
#define SIZE_CALL_NEAR_REL      5       /* Length of Call NEAR (relative) instr */

#define MI_LMSW_OPCODE          0x01    /* LMSW */

#define MI_GET_CRx_OPCODE       0x20    /* MOV r32,CRx   */
#define MI_GET_DRx_OPCODE       0x21    /* MOV r32,DRx   */
#define MI_SET_CRx_OPCODE       0x22    /* MOV CRx,r32   */
#define MI_SET_DRx_OPCODE       0x23    /* MOV DRx,r32   */
#define MI_GET_TRx_OPCODE       0x24    /* MOV r32,TRx   */
#define MI_SET_TRx_OPCODE       0x26    /* MOV TRx,r32   */

#define MI_MOV_REG8_MEM8        0x8A    /* MOV reg8,mem8 */
#define MI_MOV_SEG_MEM_OPCODE   0x8e    /* MOV seg,r/m16 */

/* WORD structure
*/
struct w_s {
        uchar_t lobyte;
        uchar_t hibyte;
};
#define LowByte         lobyte
#define HighByte        hibyte

/* DWORD structure
*/
struct dw_s {
        ushort_t loword;
        ushort_t hiword;
};
#define LowWord         loword
#define HighWord        hiword

/* Far pointer structure
*/
struct  FarPtr {
        ushort_t Offst;
        ushort_t Segmt;
};

/* Far 32 bit pointer structure
*/
struct FarPtr32 {
        ulong_t Offst32;        /* 32 bit offset */
        ushort_t Segmt32;       /* segment       */
        ushort_t Pad32;         /* segment pad   */
};

/***    RETF16 - 16 bit RETF frame definition
 *
 *      16 bit RETF frame structure
 */

typedef struct retf16_s {
        ushort_t retf16_ip;
        ushort_t retf16_cs;
} RETF16;

typedef RETF16 *PRETF16;

/***    RETF32 - 32 bit RETF frame definition
 *
 *      32 bit RETF frame structure
 */

typedef struct retf32_s {
        ulong_t retf32_eip;
        ushort_t retf32_cs;
        ushort_t retf32_padcs;
} RETF32;

typedef RETF32 *PRETF32;

/***    IRET16 - 16 bit IRET frame definition
 *
 *      16 bit IRET frame structure
 */

typedef struct iret16_s {
        ushort_t iret16_ip;
        ushort_t iret16_cs;
        ushort_t iret16_flag;
} IRET16;

typedef IRET16 *PIRET16;

/* 16 bit Iret stack frame without privilege level transition
*/
struct Iret_s {
        struct  FarPtr  I_CSIP;
        ushort_t I_FLAGS;
};

struct IretFrame {
        ushort_t IretIP ;
        ushort_t IretCS ;
        ushort_t IretFLAGS;
};

/* ASM IretCSIP EQU     <DWORD PTR IretIP> */

/***    IRET32 - 32 bit IRET frame definition
 *
 *      32 bit IRET frame structure
 */

typedef struct iret32_s {
        ulong_t iret32_eip;
        ushort_t iret32_cs;
        ushort_t iret32_padcs;
        ulong_t iret32_eflag;
} IRET32;

typedef IRET32 *PIRET32;

/* 32 bit Iret stack frame without privilege level transition
*/
struct Iret32_s {
        struct  FarPtr32 I32_CSEIP;
        ulong_t I32_EFLAGS;
};
/* ASM
I32_CS          EQU     <I32_CSEIP.Segmt32>
I32_EIP         EQU     <I32_CSEIP.Offst32>
I32_IP          EQU     <I32_CSEIP.Offst32.loword>
I32_FLAGS       EQU     <I32_EFLAGS.loword>
*/

/***    PLTIRET16 - 16 bit IRET frame definition
 *
 *      16 bit IRET frame structure with privilege level transtion
 */

typedef struct pltiret16_s {
        ushort_t pltiret16_ip;
        ushort_t pltiret16_cs;
        ushort_t pltiret16_flag;
        ushort_t pltiret16_sp;
        ushort_t pltiret16_ss;
} PLTIRET16;

typedef PLTIRET16 *PPLTIRET16;

/* 16 bit Protected mode iret stack frame with privilege level transition
*/
struct PLTIret_s {
        struct  FarPtr  PI_CSIP;
        ushort_t PI_FLAGS;
        struct  FarPtr  PI_SSSP;
};

struct PLTIretFrame {
        ushort_t PLTIretIP;
        ushort_t PLTIretCS;
        ushort_t PLTIretFLAGS;
        ushort_t PLTIretSP;
        ushort_t PLTIretSS;
};

/* ASM
PLTIretCSIP     EQU     DWORD PTR PLTIretIP
PLTIretSSSP     EQU     DWORD PTR PLTIretSP
*/

/***    PLTIRET32 - 32 bit IRET frame definition
 *
 *      32 bit IRET frame structure with privilege level transtion
 */

typedef struct pltiret32_s {
        ulong_t pltiret32_eip;
        ushort_t pltiret32_cs;
        ushort_t pltiret32_padcs;
        ulong_t pltiret32_eflag;
        ulong_t pltiret32_esp;
        ushort_t pltiret32_ss;
        ushort_t pltiret32_padss;
} PLTIRET32;

typedef PLTIRET32 *PPLTIRET32;

/* 32 bit Protected mode iret stack frame with privilege level transition
*/
struct PLTIret32_s {
        struct  FarPtr32 PI32_CSEIP;
        ulong_t PI32_EFLAGS;
        struct  FarPtr32 PI32_SSESP;
};
/* ASM
PI32_CS         EQU     <PI32_CSEIP.Segmt32>
PI32_EIP        EQU     <PI32_CSEIP.Offst32>
PI32_SS         EQU     <PI32_SSESP.Segmt32>
PI32_ESP        EQU     <PI32_SSESP.Offst32>
PI32_FLAGS      EQU     <WORD PTR PI32_EFLAGS>
*/

/* Generic 32-bit pointer structure
*/
/* XLATOFF */
union ptr_u {
        struct FarPtr   ptr_far16;      /* 16-bit far pointer */
        ulong_t         ptr_flat;       /* 32-bit flat pointer */
};
typedef union ptr_u     ptr_t;          /* Generic pointer type */

#define ptr_sel         ptr_far16.Segmt
#define ptr_off         ptr_far16.Offst
/* XLATON */

/* ASM
ptr_t   STRUC
        ptr_flat        DD      ?
ptr_t   ENDS
ptr_off         equ     <ptr_flat.Offst>
ptr_sel         equ     <ptr_flat.Segmt>
*/


/* PUSHA stack frame
*/
struct pusha_s {
        ushort_t pas_di;
        ushort_t pas_si;
        ushort_t pas_bp;
        ushort_t pas_sp;
        ushort_t pas_bx;
        ushort_t pas_dx;
        ushort_t pas_cx;
        ushort_t pas_ax;
};

/* PUSHAD stack frame
*/
struct  pushad_s {
        ulong_t pads_edi;
        ulong_t pads_esi;
        ulong_t pads_ebp;
        ulong_t pads_esp;
        ulong_t pads_ebx;
        ulong_t pads_edx;
        ulong_t pads_ecx;
        ulong_t pads_eax;
};

/* ASM
pads_di EQU     <WORD PTR pads_edi>
pads_si EQU     <WORD PTR pads_esi>
pads_bp EQU     <WORD PTR pads_ebp>
pads_sp EQU     <WORD PTR pads_esp>
pads_bx EQU     <WORD PTR pads_ebx>
pads_dx EQU     <WORD PTR pads_edx>
pads_cx EQU     <WORD PTR pads_ecx>
pads_ax EQU     <WORD PTR pads_eax>
*/

#endif /* __MI__ */


/* NOINC */
#if __IBMC__ || __IBMCPP__
   #pragma info( none )
      #ifndef __CHKHDR__
         #pragma info( restore )
      #endif
   #pragma info( restore )
#endif
/* INC */
