import "..\exdi.idl";

interface IeXdiX86_64Context;
        // HRESULT GetContext ([in, out] PCONTEXT_X86_64 pContext);
        // HRESULT SetContext ([in] CONTEXT_X86_64 Context);

cpp_quote("// The following constants are bit definitions for the ModeFlags value in CONTEXT_X86_64.")
cpp_quote("// They are provided to allow debuggers to correctly disassemble instructions based on")
cpp_quote("// the current operating mode of the processor.")

cpp_quote("#define X86_64_MODE_D     (0x0001) // D bit from the current CS selector")
cpp_quote("#define X86_64_MODE_L     (0x0002) // L bit (long mode) from the current CS selector")
cpp_quote("#define X86_64_MODE_LME   (0x0004) // LME bit (lomg mode enable) from extended feature MSR")
cpp_quote("#define X86_64_MODE_REX   (0x0008) // REX bit (register extension) from extended feature MSR")

typedef 
    struct _SEG64_DESC_INFO
    {
        DWORD64 SegBase;
        DWORD64 SegLimit;
        DWORD   SegFlags;
    } SEG64_DESC_INFO;

typedef 
    struct _SSE_REG
    {
        DWORD Reg0;
        DWORD Reg1;
        DWORD Reg2;
        DWORD Reg3;
    } SSE_REG;

#define NUM_SSE_REGS    16

typedef
    struct _CONTEXT_X86_64
    {
        struct 
        {
            BOOL fSegmentRegs;
            BOOL fControlRegs;
            BOOL fIntegerRegs;
            BOOL fFloatingPointRegs;
            BOOL fDebugRegs;
			BOOL fSegmentDescriptors;
			BOOL fSSERegisters;
			BOOL fSystemRegisters;
        }       RegGroupSelection;  // These flags are used to select groups of registers only 
                                    // (instead of the totality) for reading or writing.
        // both Segment & Control registers (used if either RegGroupSelection.fSegmentRegs or
        //  RegGroupSelection.fControlRegs is TRUE).
        DWORD   SegCs;
        DWORD   SegSs;        
        // Segment registers (used if RegGroupSelection.fSegmentRegs is TRUE).
        //  except CS and SS which are in "Segment and Control" - see above
        DWORD   SegGs;
        DWORD   SegFs;
        DWORD   SegEs;
        DWORD   SegDs;
		// Mode flags define the current processor mode (16/32/64 bit)
		DWORD64   ModeFlags;
        // Control registers (used if RegGroupSelection.fControlRegs is TRUE).
        //  except CS and SS which are in "Segment and Control" - see above
        DWORD64	  EFlags;
        DWORD64   Rbp;
        DWORD64   Rip;
        DWORD64   Rsp;
        // Integer registers (used if RegGroupSelection.fIntegerRegs is TRUE).
        DWORD64   Rax;
        DWORD64   Rbx;
        DWORD64   Rcx;
        DWORD64   Rdx;
        DWORD64   Rsi;
        DWORD64   Rdi;
		DWORD64   R8;
		DWORD64   R9;
		DWORD64   R10;
		DWORD64   R11;
		DWORD64   R12;
		DWORD64   R13;
		DWORD64   R14;
		DWORD64   R15;
        // Floating point registers (used if RegGroupSelection.fFloatingPointRegs is TRUE).
        DWORD   ControlWord;
        DWORD   StatusWord;
        DWORD   TagWord;
        DWORD   ErrorOffset;
        DWORD   ErrorSelector;
        DWORD   DataOffset;
        DWORD   DataSelector;
        BYTE    RegisterArea [SIZE_OF_80387_REGISTERS_IN_BYTES];
        // Debug registers (used if RegGroupSelection.fDebugRegs is TRUE)
        DWORD64   Dr0;
        DWORD64   Dr1;
        DWORD64   Dr2;
        DWORD64	  Dr3;
        DWORD64   Dr6;
        DWORD64   Dr7;
		// Descriptors and base registers (used if RegGroupSelection.fSegmentDescriptors is TRUE)
		SEG64_DESC_INFO DescriptorCs;
		SEG64_DESC_INFO DescriptorSs;
		SEG64_DESC_INFO DescriptorGs;
		SEG64_DESC_INFO DescriptorFs;
		SEG64_DESC_INFO DescriptorEs;
		SEG64_DESC_INFO DescriptorDs;
		DWORD64 IDTBase;
		DWORD64 IDTLimit;
		DWORD64 GDTBase;
		DWORD64 GDTLimit;
		DWORD SelLDT;
		SEG64_DESC_INFO SegLDT;
		DWORD SelTSS;
		SEG64_DESC_INFO SegTSS;
		// System registers (used if RegGroupSelection.fSystemRegisters is TRUE)
		DWORD64 RegCr0;
		DWORD64 RegCr2;
		DWORD64 RegCr3;
		DWORD64 RegCr4;
		DWORD64 RegCr8;			// Cr8 - Task priority register.
		// SSE registers (used if RegGroupSelection.fSSERegisters is TRUE)
		DWORD RegMXCSR;
		SSE_REG RegSSE[NUM_SSE_REGS];
    } CONTEXT_X86_64, *PCONTEXT_X86_64;


/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// IeXdiX86_64Context
//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////

// X86_64 context access interface

[
	object,
	uuid(4795B125-6CDE-4e76-B8D3-D5ED69ECE739),
	helpstring("IeXdiX86_64Context interface - eXdi Context access for 64 Bit X86 processors 1.0 for Platform Builder 3.0 debugger - Microsoft 1999"),
	pointer_default(ref)
]

interface IeXdiX86_64Context : IUnknown
{


/*++

Routine Name:

    GetContext

Routine Description:

    Read Context - Read a set of CPU / Co-Proc registers that define the state of the target
                    The CONTEXT.RegGroupSelection bitfield allow to select which group of register need to be read only 

Argument(s):

    pContext        - Return context (CPU dependant structure). 
                        Note: The context is also passed in to indicate only the RegGroupSelection (which reg groups are read)
    
Return Value:

    Error status:
        S_OK:                            Function successful
        EXDI_E_CANNOTWHILETGTRUNNING     Cannot proceed while target running. Must halt the target first.
                                            Note: this error is generated only if the probe / target does not support this operation "on the fly". 
                                            see DEBUG_ACCESS_CAPABILITIES_STRUCT.fReadRegWhileRunning
        EXDI_E_NOTIMPL:                  Not implemented
        EXDI_E_OUTOFMEMORY:              Failed to allocate necessary memory
        EXDI_E_INVALIDARG:               One or more arguments are invalid
        EXDI_E_ABORT:                    Operation aborted
        EXDI_E_FAIL:                     Unspecified failure
        EXDI_E_COMMUNICATION:            Communication error between host driver and target
        EXDI_E_USEDBYCONCURENTTHREAD:    Cannot proceed immediately because resource is already used by concurent thread.

--*/

HRESULT GetContext 
(
	[in, out] PCONTEXT_X86_64 pContext
);


/*++

Routine Name:

    SetContext

Routine Description:

    Write Context - Write a set of CPU / Co-Proc registers that define the state of the target
                    The CONTEXT.RegGroupSelection bitfield allow to select which group of register need to be written only 

Argument(s):

    pContext        - Return context (CPU dependant structure). 
                        Note: The context is also passed in to indicate only the RegGroupSelection (which reg groups are read)
    
Return Value:

    Error status:
        S_OK:                            Function successful
        EXDI_E_CANNOTWHILETGTRUNNING     Cannot proceed while target running. Must halt the target first.
                                            Note: this error is generated only if the probe / target does not support this operation "on the fly". 
                                            see DEBUG_ACCESS_CAPABILITIES_STRUCT.fWriteRegWhileRunning
        EXDI_E_NOTIMPL:                  Not implemented
        EXDI_E_OUTOFMEMORY:              Failed to allocate necessary memory
        EXDI_E_INVALIDARG:               One or more arguments are invalid
        EXDI_E_ABORT:                    Operation aborted
        EXDI_E_FAIL:                     Unspecified failure
        EXDI_E_COMMUNICATION:            Communication error between host driver and target
        EXDI_E_USEDBYCONCURENTTHREAD:    Cannot proceed immediately because resource is already used by concurent thread.

--*/

HRESULT SetContext 
(
	[in] CONTEXT_X86_64 Context
);


}; // interface IeXdiX86_64Context
