summaryrefslogtreecommitdiff
path: root/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32
diff options
context:
space:
mode:
Diffstat (limited to 'SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32')
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c242
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.h31
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchReadGroupRegister.c210
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchRegisters.h156
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S360
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm365
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/DebugException.h36
7 files changed, 1400 insertions, 0 deletions
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c
new file mode 100644
index 0000000000..ab724ff3d6
--- /dev/null
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c
@@ -0,0 +1,242 @@
+/** @file
+ Public include file for Debug Port Library.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ 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.
+
+**/
+
+#include "DebugAgent.h"
+
+/**
+ Read the offset of FP / MMX / XMM registers by register index.
+
+ @param[in] Index Register index.
+ @param[out] Width Register width returned.
+
+ @return Offset in register address range.
+
+**/
+UINT16
+ArchReadFxStatOffset (
+ IN UINT8 Index,
+ OUT UINT8 *Width
+ )
+{
+ if (Index < SOFT_DEBUGGER_REGISTER_ST0) {
+ switch (Index) {
+ case SOFT_DEBUGGER_REGISTER_FP_FCW:
+ *Width = (UINT8) sizeof (UINT16);
+ return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Fcw);
+
+ case SOFT_DEBUGGER_REGISTER_FP_FSW:
+ *Width = (UINT8) sizeof (UINT16);
+ return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Fsw);
+
+ case SOFT_DEBUGGER_REGISTER_FP_FTW:
+ *Width = (UINT8) sizeof (UINT16);
+ return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Ftw);
+
+ case SOFT_DEBUGGER_REGISTER_FP_OPCODE:
+ *Width = (UINT8) sizeof (UINT16);
+ return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Opcode);
+
+ case SOFT_DEBUGGER_REGISTER_FP_EIP:
+ *Width = (UINT8) sizeof (UINTN);
+ return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Eip);
+
+ case SOFT_DEBUGGER_REGISTER_FP_CS:
+ *Width = (UINT8) sizeof (UINT16);
+ return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Cs);
+
+ case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:
+ *Width = (UINT8) sizeof (UINTN);
+ return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, DataOffset);
+
+ case SOFT_DEBUGGER_REGISTER_FP_DS:
+ *Width = (UINT8) sizeof (UINT16);
+ return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Ds);
+
+ case SOFT_DEBUGGER_REGISTER_FP_MXCSR:
+ *Width = (UINT8) sizeof (UINTN);
+ return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Mxcsr);
+
+ case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:
+ *Width = (UINT8) sizeof (UINTN);
+ return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Mxcsr_Mask);
+ }
+ }
+
+ if (Index < SOFT_DEBUGGER_REGISTER_XMM0) {
+ *Width = 10;
+ } else if (Index < SOFT_DEBUGGER_REGISTER_MM0 ) {
+ *Width = 16;
+ } else {
+ *Width = 8;
+ Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;
+ }
+
+ return (UINT16)(OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16);
+}
+
+/**
+ Write specified register into save CPU context.
+
+ @param[in] CpuContext Pointer to saved CPU context.
+ @param[in] Index Register index value.
+ @param[in] Offset Offset in register address range.
+ @param[in] Width Data width to read.
+ @param[in] RegisterBuffer Pointer to input buffer with data.
+
+**/
+VOID
+ArchWriteRegisterBuffer (
+ IN DEBUG_CPU_CONTEXT *CpuContext,
+ IN UINT8 Index,
+ IN UINT8 Offset,
+ IN UINT8 Width,
+ IN UINT8 *RegisterBuffer
+ )
+{
+ UINT8 *Buffer;
+ if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {
+ Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_IA32_FX_SAVE_STATE) + Index * 4;
+ } else {
+ //
+ // If it is MMX register, adjust its index position
+ //
+ if (Index >= SOFT_DEBUGGER_REGISTER_MM0) {
+ Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;
+ }
+ //
+ // FPU/MMX/XMM registers
+ //
+ Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, &Width);
+ }
+
+ CopyMem (Buffer + Offset, RegisterBuffer, Width);
+}
+
+/**
+ Read register value from saved CPU context.
+
+ @param[in] CpuContext Pointer to saved CPU context.
+ @param[in] Index Register index value.
+ @param[in] Offset Offset in register address range
+ @param[in] Width Data width to read.
+
+ @return The address of register value.
+
+**/
+UINT8 *
+ArchReadRegisterBuffer (
+ IN DEBUG_CPU_CONTEXT *CpuContext,
+ IN UINT8 Index,
+ IN UINT8 Offset,
+ IN UINT8 *Width
+ )
+{
+ UINT8 *Buffer;
+
+ if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {
+ Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_IA32_FX_SAVE_STATE) + Index * 4;
+ if (*Width == 0) {
+ *Width = (UINT8) sizeof (UINTN);
+ }
+ } else {
+ //
+ // FPU/MMX/XMM registers
+ //
+ Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, Width);
+ }
+
+ return Buffer;
+}
+
+/**
+ Read group register of common registers.
+
+ @param[in] CpuContext Pointer to saved CPU context.
+ @param[in] RegisterGroup Pointer to Group registers.
+
+**/
+VOID
+ReadRegisterGroup (
+ IN DEBUG_CPU_CONTEXT *CpuContext,
+ IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP *RegisterGroup
+ )
+{
+ RegisterGroup->Cs = (UINT16) CpuContext->Cs;
+ RegisterGroup->Ds = (UINT16) CpuContext->Ds;
+ RegisterGroup->Es = (UINT16) CpuContext->Es;
+ RegisterGroup->Fs = (UINT16) CpuContext->Fs;
+ RegisterGroup->Gs = (UINT16) CpuContext->Gs;
+ RegisterGroup->Ss = (UINT16) CpuContext->Ss;
+ RegisterGroup->Eflags = CpuContext->Eflags;
+ RegisterGroup->Ebp = CpuContext->Ebp;
+ RegisterGroup->Eip = CpuContext->Eip;
+ RegisterGroup->Esp = CpuContext->Esp;
+ RegisterGroup->Eax = CpuContext->Eax;
+ RegisterGroup->Ebx = CpuContext->Ebx;
+ RegisterGroup->Ecx = CpuContext->Ecx;
+ RegisterGroup->Edx = CpuContext->Edx;
+ RegisterGroup->Esi = CpuContext->Esi;
+ RegisterGroup->Edi = CpuContext->Edi;
+ RegisterGroup->Dr0 = CpuContext->Dr0;
+ RegisterGroup->Dr1 = CpuContext->Dr1;
+ RegisterGroup->Dr2 = CpuContext->Dr2;
+ RegisterGroup->Dr3 = CpuContext->Dr3;
+ RegisterGroup->Dr6 = CpuContext->Dr6;
+ RegisterGroup->Dr7 = CpuContext->Dr7;
+}
+
+/**
+ Initialize IDT entries to support source level debug.
+
+**/
+VOID
+InitializeDebugIdt (
+ VOID
+ )
+{
+ IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
+ UINTN InterruptHandler;
+ IA32_DESCRIPTOR IdtDescriptor;
+ UINTN Index;
+ UINT16 CodeSegment;
+
+ AsmReadIdtr (&IdtDescriptor);
+
+ //
+ // Use current CS as the segment selector of interrupt gate in IDT
+ //
+ CodeSegment = AsmReadCs ();
+
+ IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
+
+ for (Index = 0; Index < 20; Index ++) {
+ if ((PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {
+ //
+ // If the exception is masked to be reserved, skip it
+ //
+ continue;
+ }
+ InterruptHandler = (UINTN)&Exception0Handle + Index * ExceptionStubHeaderSize;
+ IdtEntry[Index].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
+ IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
+ IdtEntry[Index].Bits.Selector = CodeSegment;
+ IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
+ }
+
+ InterruptHandler = (UINTN) &TimerInterruptHandle;
+ IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
+ IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
+ IdtEntry[Index].Bits.Selector = CodeSegment;
+ IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
+}
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.h
new file mode 100644
index 0000000000..7df3cb9415
--- /dev/null
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.h
@@ -0,0 +1,31 @@
+/** @file
+ IA32 specific defintions for debug agent library instance.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ 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.
+
+**/
+
+#ifndef _ARCH_DEBUG_SUPPORT_H_
+#define _ARCH_DEBUG_SUPPORT_H_
+
+#include "ArchRegisters.h"
+#include "TransferProtocol.h"
+
+typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_IA32 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP;
+typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM_IA32 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM;
+typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE_IA32 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE;
+
+#define DEBUG_SW_BREAKPOINT_SYMBOL 0xcc
+
+#define DEBUG_ARCH_SYMBOL DEBUG_DATA_BREAK_CPU_ARCH_IA32
+
+typedef DEBUG_DATA_IA32_SYSTEM_CONTEXT DEBUG_CPU_CONTEXT;
+
+#endif
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchReadGroupRegister.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchReadGroupRegister.c
new file mode 100644
index 0000000000..59ebd00255
--- /dev/null
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchReadGroupRegister.c
@@ -0,0 +1,210 @@
+/** @file
+ IA32 Group registers read support functions.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ 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.
+
+**/
+
+#include "DebugAgent.h"
+
+/**
+ Read group register of Segment Base.
+
+ @param[in] CpuContext Pointer to saved CPU context.
+ @param[in] RegisterGroupSegBase Pointer to Group registers.
+
+**/
+VOID
+ReadRegisterGroupSegBase (
+ IN DEBUG_CPU_CONTEXT *CpuContext,
+ IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE *RegisterGroupSegBase
+ )
+{
+ IA32_DESCRIPTOR *Ia32Descriptor;
+ IA32_GDT *Ia32Gdt;
+ UINTN Index;
+
+ Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;
+ Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);
+
+ Index = CpuContext->Cs / 8;
+ RegisterGroupSegBase->CsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
+ Index = CpuContext->Ss / 8;
+ RegisterGroupSegBase->SsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
+ Index = CpuContext->Gs / 8;
+ RegisterGroupSegBase->GsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
+ Index = CpuContext->Fs / 8;
+ RegisterGroupSegBase->FsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
+ Index = CpuContext->Es / 8;
+ RegisterGroupSegBase->EsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
+ Index = CpuContext->Ds / 8;
+ RegisterGroupSegBase->DsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);
+
+ RegisterGroupSegBase->LdtBas = 0;
+ RegisterGroupSegBase->TssBas = 0;
+}
+
+/**
+ Read gourp register of Segment Limit.
+
+ @param[in] CpuContext Pointer to saved CPU context.
+ @param[in] RegisterGroupSegLim Pointer to Group registers.
+
+**/
+VOID
+ReadRegisterGroupSegLim (
+ IN DEBUG_CPU_CONTEXT *CpuContext,
+ IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM *RegisterGroupSegLim
+ )
+{
+ IA32_DESCRIPTOR *Ia32Descriptor;
+ IA32_GDT *Ia32Gdt;
+ UINTN Index;
+
+ Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;
+ Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);
+
+ Index = CpuContext->Cs / 8;
+ RegisterGroupSegLim->CsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
+ if (Ia32Gdt[Index].Bits.Granularity == 1) {
+ RegisterGroupSegLim->CsLim = (RegisterGroupSegLim->CsLim << 12) | 0xfff;
+ }
+
+ Index = CpuContext->Ss / 8;
+ RegisterGroupSegLim->SsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
+ if (Ia32Gdt[Index].Bits.Granularity == 1) {
+ RegisterGroupSegLim->SsLim = (RegisterGroupSegLim->SsLim << 12) | 0xfff;
+ }
+
+ Index = CpuContext->Gs / 8;
+ RegisterGroupSegLim->GsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
+ if (Ia32Gdt[Index].Bits.Granularity == 1) {
+ RegisterGroupSegLim->GsLim = (RegisterGroupSegLim->GsLim << 12) | 0xfff;
+ }
+
+ Index = CpuContext->Fs / 8;
+ RegisterGroupSegLim->FsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
+ if (Ia32Gdt[Index].Bits.Granularity == 1) {
+ RegisterGroupSegLim->FsLim = (RegisterGroupSegLim->FsLim << 12) | 0xfff;
+ }
+
+ Index = CpuContext->Es / 8;
+ RegisterGroupSegLim->EsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
+ if (Ia32Gdt[Index].Bits.Granularity == 1) {
+ RegisterGroupSegLim->EsLim = (RegisterGroupSegLim->EsLim << 12) | 0xfff;
+ }
+
+ Index = CpuContext->Ds / 8;
+ RegisterGroupSegLim->DsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);
+ if (Ia32Gdt[Index].Bits.Granularity == 1) {
+ RegisterGroupSegLim->DsLim = (RegisterGroupSegLim->DsLim << 12) | 0xfff;
+ }
+
+ RegisterGroupSegLim->LdtLim = 0xffff;
+ RegisterGroupSegLim->TssLim = 0xffff;
+}
+
+/**
+ Read group register by group index.
+
+ @param[in] CpuContext Pointer to saved CPU context.
+ @param[in] GroupIndex Group Index.
+
+ @retval RETURN_SUCCESS Read successfully.
+ @retval RETURN_NOT_SUPPORTED Group index cannot be supported.
+
+**/
+RETURN_STATUS
+ArchReadRegisterGroup (
+ IN DEBUG_CPU_CONTEXT *CpuContext,
+ IN UINT8 GroupIndex
+ )
+{
+ DEBUG_DATA_REPONSE_READ_REGISTER_GROUP RegisterGroup;
+ DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM RegisterGroupSegLim;
+ DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE RegisterGroupSegBase;
+
+ switch (GroupIndex) {
+ case SOFT_DEBUGGER_REGISTER_GROUP_GPDRS32:
+ ReadRegisterGroup (CpuContext, &RegisterGroup);
+ SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP));
+ break;
+
+ case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_LIMITS32:
+ ReadRegisterGroupSegLim (CpuContext, &RegisterGroupSegLim);
+ SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroupSegLim, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM));
+ break;
+
+ case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_BASES32:
+ ReadRegisterGroupSegBase (CpuContext, &RegisterGroupSegBase);
+ SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroupSegBase, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE));
+ break;
+
+ default:
+ return RETURN_UNSUPPORTED;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Read segment selector by register index.
+
+ @param[in] CpuContext Pointer to saved CPU context.
+ @param[in] RegisterIndex Register Index.
+
+ @return Value of segment selector.
+
+**/
+UINT64
+ReadRegisterSelectorByIndex (
+ IN DEBUG_CPU_CONTEXT *CpuContext,
+ IN UINT8 RegisterIndex
+ )
+{
+ IA32_DESCRIPTOR *Ia32Descriptor;
+ IA32_GDT *Ia32Gdt;
+ UINT16 Selector;
+ UINT32 Data32;
+
+ Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;
+ Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);
+
+ Selector = 0;
+
+ switch (RegisterIndex) {
+ case SOFT_DEBUGGER_REGISTER_CSAS:
+ Selector = (UINT16) CpuContext->Cs;
+ break;
+ case SOFT_DEBUGGER_REGISTER_SSAS:
+ Selector = (UINT16) CpuContext->Ss;
+ break;
+ case SOFT_DEBUGGER_REGISTER_GSAS:
+ Selector = (UINT16) CpuContext->Gs;
+ break;
+ case SOFT_DEBUGGER_REGISTER_FSAS:
+ Selector = (UINT16) CpuContext->Fs;
+ break;
+ case SOFT_DEBUGGER_REGISTER_ESAS:
+ Selector = (UINT16) CpuContext->Es;
+ break;
+ case SOFT_DEBUGGER_REGISTER_DSAS:
+ Selector = (UINT16) CpuContext->Ds;
+ case SOFT_DEBUGGER_REGISTER_LDTAS:
+ case SOFT_DEBUGGER_REGISTER_TSSAS:
+ return 0x00820000;
+ break;
+ }
+
+ Data32 = (UINT32) RShiftU64 (Ia32Gdt[Selector / 8].Uint64, 24);
+ return (Data32 & (UINT32)(~0xff)) | Selector;
+
+}
+
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchRegisters.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchRegisters.h
new file mode 100644
index 0000000000..3c279589e7
--- /dev/null
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchRegisters.h
@@ -0,0 +1,156 @@
+/** @file
+ IA32 register defintions needed by debug transfer protocol.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ 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.
+
+**/
+
+#ifndef _ARCH_REGISTERS_H_
+#define _ARCH_REGISTERS_H_
+
+///
+/// FXSAVE_STATE
+/// FP / MMX / XMM registers (see fxrstor instruction definition)
+///
+typedef struct {
+ UINT16 Fcw;
+ UINT16 Fsw;
+ UINT16 Ftw;
+ UINT16 Opcode;
+ UINT32 Eip;
+ UINT16 Cs;
+ UINT16 Reserved1;
+ UINT32 DataOffset;
+ UINT16 Ds;
+ UINT8 Reserved2[2];
+ UINT32 Mxcsr;
+ UINT32 Mxcsr_Mask;
+ UINT8 St0Mm0[10];
+ UINT8 Reserved3[6];
+ UINT8 St1Mm1[10];
+ UINT8 Reserved4[6];
+ UINT8 St2Mm2[10];
+ UINT8 Reserved5[6];
+ UINT8 St3Mm3[10];
+ UINT8 Reserved6[6];
+ UINT8 St4Mm4[10];
+ UINT8 Reserved7[6];
+ UINT8 St5Mm5[10];
+ UINT8 Reserved8[6];
+ UINT8 St6Mm6[10];
+ UINT8 Reserved9[6];
+ UINT8 St7Mm7[10];
+ UINT8 Reserved10[6];
+ UINT8 Xmm0[16];
+ UINT8 Xmm1[16];
+ UINT8 Xmm2[16];
+ UINT8 Xmm3[16];
+ UINT8 Xmm4[16];
+ UINT8 Xmm5[16];
+ UINT8 Xmm6[16];
+ UINT8 Xmm7[16];
+ UINT8 Reserved11[14 * 16];
+} DEBUG_DATA_IA32_FX_SAVE_STATE;
+
+///
+/// IA-32 processor context definition
+///
+typedef struct {
+ DEBUG_DATA_IA32_FX_SAVE_STATE FxSaveState;
+ UINT32 Dr0;
+ UINT32 Dr1;
+ UINT32 Dr2;
+ UINT32 Dr3;
+ UINT32 Dr6;
+ UINT32 Dr7;
+ UINT32 Eflags;
+ UINT32 Ldtr;
+ UINT32 Tr;
+ UINT32 Gdtr[2];
+ UINT32 Idtr[2];
+ UINT32 Eip;
+ UINT32 Gs;
+ UINT32 Fs;
+ UINT32 Es;
+ UINT32 Ds;
+ UINT32 Cs;
+ UINT32 Ss;
+ UINT32 Cr0;
+ UINT32 Cr1; ///< Reserved
+ UINT32 Cr2;
+ UINT32 Cr3;
+ UINT32 Cr4;
+ UINT32 Edi;
+ UINT32 Esi;
+ UINT32 Ebp;
+ UINT32 Esp;
+ UINT32 Edx;
+ UINT32 Ecx;
+ UINT32 Ebx;
+ UINT32 Eax;
+} DEBUG_DATA_IA32_SYSTEM_CONTEXT;
+
+///
+/// IA32 GROUP register
+///
+typedef struct {
+ UINT16 Cs;
+ UINT16 Ds;
+ UINT16 Es;
+ UINT16 Fs;
+ UINT16 Gs;
+ UINT16 Ss;
+ UINT32 Eflags;
+ UINT32 Ebp;
+ UINT32 Eip;
+ UINT32 Esp;
+ UINT32 Eax;
+ UINT32 Ebx;
+ UINT32 Ecx;
+ UINT32 Edx;
+ UINT32 Esi;
+ UINT32 Edi;
+ UINT32 Dr0;
+ UINT32 Dr1;
+ UINT32 Dr2;
+ UINT32 Dr3;
+ UINT32 Dr6;
+ UINT32 Dr7;
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_IA32;
+
+///
+/// IA32 Segment Limit GROUP register
+///
+typedef struct {
+ UINT32 CsLim;
+ UINT32 SsLim;
+ UINT32 GsLim;
+ UINT32 FsLim;
+ UINT32 EsLim;
+ UINT32 DsLim;
+ UINT32 LdtLim;
+ UINT32 TssLim;
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM_IA32;
+
+///
+/// IA32 Segment Base GROUP register
+///
+typedef struct {
+ UINT32 CsBas;
+ UINT32 SsBas;
+ UINT32 GsBas;
+ UINT32 FsBas;
+ UINT32 EsBas;
+ UINT32 DsBas;
+ UINT32 LdtBas;
+ UINT32 TssBas;
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE_IA32;
+
+#endif
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
new file mode 100644
index 0000000000..365947f4d5
--- /dev/null
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
@@ -0,0 +1,360 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+# 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:
+#
+# AsmFuncs.S
+#
+# Abstract:
+#
+# Debug interrupt handle functions.
+#
+#------------------------------------------------------------------------------
+
+#include "DebugException.h"
+
+ASM_GLOBAL ASM_PFX(InterruptProcess)
+ASM_GLOBAL ASM_PFX(Exception0Handle)
+ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)
+ASM_GLOBAL ASM_PFX(TimerInterruptHandle)
+ASM_GLOBAL ASM_PFX(CommonEntry)
+
+.data
+
+ASM_PFX(ExceptionStubHeaderSize): .word ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
+
+.text
+
+ASM_PFX(Exception0Handle):
+ cli
+ pushl %eax
+ mov $0, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception1Handle):
+ cli
+ pushl %eax
+ mov $1, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception2Handle):
+ cli
+ pushl %eax
+ mov $2, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception3Handle):
+ cli
+ pushl %eax
+ mov $3, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception4Handle):
+ cli
+ pushl %eax
+ mov $4, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception5Handle):
+ cli
+ pushl %eax
+ mov $5, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception6Handle):
+ cli
+ pushl %eax
+ mov $6, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception7Handle):
+ cli
+ pushl %eax
+ mov $7, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception8Handle):
+ cli
+ pushl %eax
+ mov $8, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception9Handle):
+ cli
+ pushl %eax
+ mov $9, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception10Handle):
+ cli
+ pushl %eax
+ mov $10, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception11Handle):
+ cli
+ pushl %eax
+ mov $11, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception12Handle):
+ cli
+ pushl %eax
+ mov $12, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception13Handle):
+ cli
+ pushl %eax
+ mov $13, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception14Handle):
+ cli
+ pushl %eax
+ mov $14, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception15Handle):
+ cli
+ pushl %eax
+ mov $15, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception16Handle):
+ cli
+ pushl %eax
+ mov $16, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception17Handle):
+ cli
+ pushl %eax
+ mov $17, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception18Handle):
+ cli
+ pushl %eax
+ mov $18, %eax
+ jmp ASM_PFX(CommonEntry)
+ASM_PFX(Exception19Handle):
+ cli
+ pushl %eax
+ mov $19, %eax
+ jmp ASM_PFX(CommonEntry)
+
+ASM_PFX(TimerInterruptHandle):
+ cli
+ pushl %eax
+ mov $32, %eax
+ jmp ASM_PFX(CommonEntry)
+
+
+ASM_PFX(CommonEntry):
+
+#---------------------------------------;
+# _CommonEntry ;
+#----------------------------------------------------------------------------;
+# The follow algorithm is used for the common interrupt routine.
+# Entry from each interrupt with a push eax and eax=interrupt number
+#
+# +---------------------+
+# + EFlags +
+# +---------------------+
+# + CS +
+# +---------------------+
+# + EIP +
+# +---------------------+
+# + Error Code +
+# +---------------------+
+# + EAX / Vector Number +
+# +---------------------+
+# + EBP +
+# +---------------------+ <-- EBP
+#
+
+# We need to determine if any extra data was pushed by the exception
+ cmpl $DEBUG_EXCEPT_DOUBLE_FAULT, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_INVALID_TSS, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_SEG_NOT_PRESENT, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_STACK_FAULT, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_GP_FAULT, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_PAGE_FAULT, %eax
+ je NoExtrPush
+ cmpl $DEBUG_EXCEPT_ALIGNMENT_CHECK, %eax
+ je NoExtrPush
+
+ pushl (%esp)
+ movl $0, 4(%esp)
+
+NoExtrPush:
+
+ pushl %ebp
+ movl %esp,%ebp
+
+ #
+ # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
+ # is 16-byte aligned
+ #
+ andl $0xfffffff0,%esp
+ subl $12,%esp
+
+## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ pushl 0x4(%ebp)
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ mov %eax, %ebx # save vector in ebx
+ leal 24(%ebp),%ecx
+ pushl %ecx # save original ESP
+ pushl (%ebp)
+ pushl %esi
+ pushl %edi
+
+## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
+ movl %cr4, %eax
+ orl $0x208,%eax
+ movl %eax, %cr4
+ pushl %eax
+ movl %cr3, %eax
+ pushl %eax
+ movl %cr2, %eax
+ pushl %eax
+ xorl %eax,%eax
+ pushl %eax
+ movl %cr0, %eax
+ pushl %eax
+
+## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+ movl %ss,%eax
+ pushl %eax
+ movzwl 16(%ebp), %eax
+ pushl %eax
+ movl %ds,%eax
+ pushl %eax
+ movl %es,%eax
+ pushl %eax
+ movl %fs,%eax
+ pushl %eax
+ movl %gs,%eax
+ pushl %eax
+
+## UINT32 Eip;
+ pushl 12(%ebp)
+
+## UINT32 Gdtr[2], Idtr[2];
+ subl $8,%esp
+ sidt (%esp)
+ subl $8,%esp
+ sgdt (%esp)
+
+## UINT32 Ldtr, Tr;
+ xorl %eax,%eax
+ strl %eax
+ pushl %eax
+ sldtl %eax
+ pushl %eax
+
+## UINT32 EFlags;
+ pushl 20(%ebp)
+
+## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ movl %dr7, %eax
+ pushl %eax
+## clear Dr7 while executing debugger itself
+ xorl %eax,%eax
+# movl %eax, %dr7
+
+ movl %dr6, %eax
+ pushl %eax
+## insure all status bits in dr6 are clear...
+ xorl %eax,%eax
+ movl %eax, %dr6
+
+ movl %dr3, %eax
+ pushl %eax
+ movl %dr2, %eax
+ pushl %eax
+ movl %dr1, %eax
+ pushl %eax
+ movl %dr0, %eax
+ pushl %eax
+
+## FX_SAVE_STATE_IA32 FxSaveState;
+ subl $512,%esp
+ movl %esp,%edi
+ .byte 0x0f, 0xae, 0x07 # fxsave [edi]
+
+## Clear Direction Flag
+ cld
+
+## Prepare parameter and call C function
+ pushl %esp
+ pushl %ebx
+ call ASM_PFX(InterruptProcess)
+ addl $8,%esp
+
+## FX_SAVE_STATE_IA32 FxSaveState;
+ movl %esp,%esi
+ .byte 0x0f, 0xae, 0x0e # fxrstor [esi]
+ addl $512,%esp
+
+## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ popl %eax
+ movl %eax, %dr0
+ popl %eax
+ movl %eax, %dr1
+ popl %eax
+ movl %eax, %dr2
+ popl %eax
+ movl %eax, %dr3
+## skip restore of dr6. We cleared dr6 during the context save.
+ addl $4,%esp
+ popl %eax
+ movl %eax, %dr7
+
+## UINT32 EFlags;
+ popl 20(%ebp)
+
+## UINT32 Ldtr, Tr;
+## UINT32 Gdtr[2], Idtr[2];
+## Best not let anyone mess with these particular registers...
+ addl $24,%esp
+
+## UINT32 Eip;
+ pop 12(%ebp)
+
+## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+## NOTE - modified segment registers could hang the debugger... We
+## could attempt to insulate ourselves against this possibility,
+## but that poses risks as well.
+##
+ popl %gs
+ popl %fs
+ popl %es
+ popl %ds
+ popl 16(%ebp)
+ popl %ss
+
+## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
+ popl %eax
+ movl %eax, %cr0
+ addl $4,%esp # not for Cr1
+ popl %eax
+ movl %eax, %cr2
+ popl %eax
+ movl %eax, %cr3
+ popl %eax
+ movl %eax, %cr4
+
+## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ popl %edi
+ popl %esi
+ addl $4,%esp # not for ebp
+ addl $4,%esp # not for esp
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %eax
+
+ movl %ebp,%esp
+ popl %ebp
+ addl $8,%esp # skip eax
+ iretl
+
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm
new file mode 100644
index 0000000000..2d2fa5fc7a
--- /dev/null
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm
@@ -0,0 +1,365 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+; 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:
+;
+; AsmFuncs.asm
+;
+; Abstract:
+;
+; Debug interrupt handle functions.
+;
+;------------------------------------------------------------------------------
+
+#include "DebugException.h"
+
+.686p
+.xmm
+.model flat,c
+
+;
+; InterruptProcess()
+;
+InterruptProcess PROTO C
+
+public Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize
+
+.data
+
+ExceptionStubHeaderSize DW Exception1Handle - Exception0Handle
+CommonEntryAddr DD CommonEntry
+
+.code
+
+Exception0Handle:
+ cli
+ push eax
+ mov eax, 0
+ jmp dword ptr [CommonEntryAddr]
+Exception1Handle:
+ cli
+ push eax
+ mov eax, 1
+ jmp dword ptr [CommonEntryAddr]
+Exception2Handle:
+ cli
+ push eax
+ mov eax, 2
+ jmp dword ptr [CommonEntryAddr]
+Exception3Handle:
+ cli
+ push eax
+ mov eax, 3
+ jmp dword ptr [CommonEntryAddr]
+Exception4Handle:
+ cli
+ push eax
+ mov eax, 4
+ jmp dword ptr [CommonEntryAddr]
+Exception5Handle:
+ cli
+ push eax
+ mov eax, 5
+ jmp dword ptr [CommonEntryAddr]
+Exception6Handle:
+ cli
+ push eax
+ mov eax, 6
+ jmp dword ptr [CommonEntryAddr]
+Exception7Handle:
+ cli
+ push eax
+ mov eax, 7
+ jmp dword ptr [CommonEntryAddr]
+Exception8Handle:
+ cli
+ push eax
+ mov eax, 8
+ jmp dword ptr [CommonEntryAddr]
+Exception9Handle:
+ cli
+ push eax
+ mov eax, 9
+ jmp dword ptr [CommonEntryAddr]
+Exception10Handle:
+ cli
+ push eax
+ mov eax, 10
+ jmp dword ptr [CommonEntryAddr]
+Exception11Handle:
+ cli
+ push eax
+ mov eax, 11
+ jmp dword ptr [CommonEntryAddr]
+Exception12Handle:
+ cli
+ push eax
+ mov eax, 12
+ jmp dword ptr [CommonEntryAddr]
+Exception13Handle:
+ cli
+ push eax
+ mov eax, 13
+ jmp dword ptr [CommonEntryAddr]
+Exception14Handle:
+ cli
+ push eax
+ mov eax, 14
+ jmp dword ptr [CommonEntryAddr]
+Exception15Handle:
+ cli
+ push eax
+ mov eax, 15
+ jmp dword ptr [CommonEntryAddr]
+Exception16Handle:
+ cli
+ push eax
+ mov eax, 16
+ jmp dword ptr [CommonEntryAddr]
+Exception17Handle:
+ cli
+ push eax
+ mov eax, 17
+ jmp dword ptr [CommonEntryAddr]
+Exception18Handle:
+ cli
+ push eax
+ mov eax, 18
+ jmp dword ptr [CommonEntryAddr]
+Exception19Handle:
+ cli
+ push eax
+ mov eax, 19
+ jmp dword ptr [CommonEntryAddr]
+
+TimerInterruptHandle:
+ cli
+ push eax
+ mov eax, 32
+ jmp dword ptr [CommonEntryAddr]
+
+CommonEntry:
+;
+; +---------------------+
+; + EFlags +
+; +---------------------+
+; + CS +
+; +---------------------+
+; + EIP +
+; +---------------------+
+; + Error Code +
+; +---------------------+
+; + EAX / Vector Number +
+; +---------------------+
+; + EBP +
+; +---------------------+ <-- EBP
+;
+ cmp eax, DEBUG_EXCEPT_DOUBLE_FAULT
+ je NoExtrPush
+ cmp eax, DEBUG_EXCEPT_INVALID_TSS
+ je NoExtrPush
+ cmp eax, DEBUG_EXCEPT_SEG_NOT_PRESENT
+ je NoExtrPush
+ cmp eax, DEBUG_EXCEPT_STACK_FAULT
+ je NoExtrPush
+ cmp eax, DEBUG_EXCEPT_GP_FAULT
+ je NoExtrPush
+ cmp eax, DEBUG_EXCEPT_PAGE_FAULT
+ je NoExtrPush
+ cmp eax, DEBUG_EXCEPT_ALIGNMENT_CHECK
+ je NoExtrPush
+
+ push [esp]
+ mov dword ptr [esp + 4], 0
+
+NoExtrPush:
+
+ push ebp
+ mov ebp, esp ; save esp in ebp
+ ;
+ ; Make stack 16-byte alignment to make sure save fxrstor later
+ ;
+ and esp, 0fffffff0h
+ sub esp, 12
+
+ ; store UINT32 Edi, Esi, Ebp, Ebx, Edx, Ecx, Eax;
+ push dword ptr [ebp + 4] ; original eax
+ push ebx
+ push ecx
+ push edx
+ mov ebx, eax ; save vector in ebx
+ mov eax, ebp
+ add eax, 4 * 6
+ push eax ; original ESP
+ push dword ptr [ebp] ; EBP
+ push esi
+ push edi
+
+ ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
+ ;; insure FXSAVE/FXRSTOR is enabled in CR4...
+ ;; ... while we're at it, make sure DE is also enabled...
+ mov eax, cr4
+ push eax ; push cr4 firstly
+ or eax, 208h
+ mov cr4, eax
+ mov eax, cr3
+ push eax
+ mov eax, cr2
+ push eax
+ push 0 ; cr0 will not saved???
+ mov eax, cr0
+ push eax
+
+ xor ecx, ecx
+ mov ecx, Ss
+ push ecx
+ mov ecx, Cs
+ push ecx
+ mov ecx, Ds
+ push ecx
+ mov ecx, Es
+ push ecx
+ mov ecx, Fs
+ push ecx
+ mov ecx, Gs
+ push ecx
+
+ ;; EIP
+ mov ecx, [ebp + 4 * 3] ; EIP
+ push ecx
+
+ ;; UINT32 Gdtr[2], Idtr[2];
+ sub esp, 8
+ sidt fword ptr [esp]
+ sub esp, 8
+ sgdt fword ptr [esp]
+
+ ;; UINT32 Ldtr, Tr;
+ xor eax, eax
+ str ax
+ push eax
+ sldt ax
+ push eax
+
+ ;; EFlags
+ mov ecx, [ebp + 4 * 5]
+ push ecx
+
+ ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ mov eax, dr7
+ push eax
+
+ ;; clear Dr7 while executing debugger itself
+ xor eax, eax
+ ;; mov dr7, eax
+
+ ;; Dr6
+ mov eax, dr6
+ push eax
+
+ ;; insure all status bits in dr6 are clear...
+ xor eax, eax
+ mov dr6, eax
+
+ mov eax, dr3
+ push eax
+ mov eax, dr2
+ push eax
+ mov eax, dr1
+ push eax
+ mov eax, dr0
+ push eax
+
+ ;; FX_SAVE_STATE_IA32 FxSaveState;
+ sub esp, 512
+ mov edi, esp
+ db 0fh, 0aeh, 00000111y ;fxsave [edi]
+
+ ;; Clear Direction Flag
+ cld
+
+ ; call the C interrupt process function
+ push esp ; Structure
+ push ebx ; vector
+ call InterruptProcess
+ add esp, 8
+
+ ;; FX_SAVE_STATE_IA32 FxSaveState;
+ mov esi, esp
+ db 0fh, 0aeh, 00001110y ; fxrstor [esi]
+ add esp, 512
+
+ ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ pop eax
+ mov dr0, eax
+ pop eax
+ mov dr1, eax
+ pop eax
+ mov dr2, eax
+ pop eax
+ mov dr3, eax
+ ;; skip restore of dr6. We cleared dr6 during the context save.
+ add esp, 4
+ pop eax
+ mov dr7, eax
+
+ ;; set EFlags
+ pop dword ptr [ebp + 4 * 5] ; set EFLAGS in stack
+
+ ;; UINT32 Ldtr, Tr;
+ ;; UINT32 Gdtr[2], Idtr[2];
+ ;; Best not let anyone mess with these particular registers...
+ add esp, 24
+
+ ;; UINT32 Eip;
+ pop dword ptr [ebp + 4 * 3] ; set EIP in stack
+
+ ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+ ;; NOTE - modified segment registers could hang the debugger... We
+ ;; could attempt to insulate ourselves against this possibility,
+ ;; but that poses risks as well.
+ ;;
+ pop gs
+ pop fs
+ pop es
+ pop ds
+ pop dword ptr [ebp + 4 * 4] ; set CS in stack
+ pop ss
+
+ ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
+ pop eax
+ mov cr0, eax
+ add esp, 4 ; skip for Cr1
+ pop eax
+ mov cr2, eax
+ pop eax
+ mov cr3, eax
+ pop eax
+ mov cr4, eax
+
+ ;; restore general register
+ pop edi
+ pop esi
+ pop dword ptr [ebp] ; save updated ebp
+ pop dword ptr [ebp + 4] ; save updated esp
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+
+ mov esp, ebp
+ pop ebp ; restore ebp maybe updated
+ pop esp ; restore esp maybe updated
+ sub esp, 4 * 3 ; restore interupt pushced stack
+
+ iretd
+
+END
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/DebugException.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/DebugException.h
new file mode 100644
index 0000000000..13a7d23a0d
--- /dev/null
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/DebugException.h
@@ -0,0 +1,36 @@
+/** @file
+ Exception defintions.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ 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.
+
+**/
+
+#ifndef _DEBUG_EXCEPTION_H_
+#define _DEBUG_EXCEPTION_H_
+
+#define DEBUG_EXCEPT_DIVIDE_ERROR 0
+#define DEBUG_EXCEPT_DEBUG 1
+#define DEBUG_EXCEPT_NMI 2
+#define DEBUG_EXCEPT_BREAKPOINT 3
+#define DEBUG_EXCEPT_OVERFLOW 4
+#define DEBUG_EXCEPT_BOUND 5
+#define DEBUG_EXCEPT_INVALID_OPCODE 6
+#define DEBUG_EXCEPT_DOUBLE_FAULT 8
+#define DEBUG_EXCEPT_INVALID_TSS 10
+#define DEBUG_EXCEPT_SEG_NOT_PRESENT 11
+#define DEBUG_EXCEPT_STACK_FAULT 12
+#define DEBUG_EXCEPT_GP_FAULT 13
+#define DEBUG_EXCEPT_PAGE_FAULT 14
+#define DEBUG_EXCEPT_FP_ERROR 16
+#define DEBUG_EXCEPT_ALIGNMENT_CHECK 17
+#define DEBUG_EXCEPT_MACHINE_CHECK 18
+#define DEBUG_EXCEPT_SIMD 19
+
+#endif