Import SourceLevelDebugPkg.
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Sun, 12 Sep 2010 06:43:36 +0000 (06:43 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Sun, 12 Sep 2010 06:43:36 +0000 (06:43 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10867 6f19259b-4bc3-4df7-8a09-765794883524

44 files changed:
SourceLevelDebugPkg/Include/Guid/DebugAgentGuid.h [new file with mode: 0644]
SourceLevelDebugPkg/Include/Ia32/ProcessorContext.h [new file with mode: 0644]
SourceLevelDebugPkg/Include/ImageDebugSupport.h [new file with mode: 0644]
SourceLevelDebugPkg/Include/Library/DebugCommunicationLib.h [new file with mode: 0644]
SourceLevelDebugPkg/Include/SoftDebuggerDefinitions.h [new file with mode: 0644]
SourceLevelDebugPkg/Include/TransferProtocol.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugMp.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugMp.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchReadGroupRegister.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchRegisters.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/DebugException.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchReadGroupRegister.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchRegisters.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.asm [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/DebugException.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.h [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugCommunicationLibUsb/DebugCommunicationLibUsb.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/DebugCommunicationLibUsb/DebugCommunicationLibUsb.inf [new file with mode: 0644]
SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c [new file with mode: 0644]
SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf [new file with mode: 0644]
SourceLevelDebugPkg/Readme.txt [new file with mode: 0644]
SourceLevelDebugPkg/SourceLevelDebugPkg.dec [new file with mode: 0644]
SourceLevelDebugPkg/SourceLevelDebugPkg.dsc [new file with mode: 0644]

diff --git a/SourceLevelDebugPkg/Include/Guid/DebugAgentGuid.h b/SourceLevelDebugPkg/Include/Guid/DebugAgentGuid.h
new file mode 100644 (file)
index 0000000..87776a3
--- /dev/null
@@ -0,0 +1,32 @@
+/** @file\r
+  This file defines the debug agent GUID for HOB and configuration table.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __EFI_DEBUG_AGNET_GUID_H__\r
+#define __EFI_DEBUG_AGENT_GUID_H__\r
+\r
+///\r
+/// This guid is used as a variable GUID for the capsule variable\r
+/// if the capsule pointer is passed through reset via a variable.\r
+///\r
+/// This guid is also used as a hob GUID for the capsule data\r
+/// when the capsule pointer is passed from PEI phase to DXE phase.\r
+///\r
+#define EFI_DEBUG_AGENT_GUID  \\r
+  { \\r
+    0x865a5a9b, 0xb85d, 0x474c, { 0x84, 0x55, 0x65, 0xd1, 0xbe, 0x84, 0x4b, 0xe2 } \\r
+  }\r
+\r
+extern EFI_GUID gEfiDebugAgentGuid;\r
+\r
+#endif\r
diff --git a/SourceLevelDebugPkg/Include/Ia32/ProcessorContext.h b/SourceLevelDebugPkg/Include/Ia32/ProcessorContext.h
new file mode 100644 (file)
index 0000000..d2759b5
--- /dev/null
@@ -0,0 +1,179 @@
+/** @file\r
+  IA32/x64 architecture specific defintions needed by debug transfer protocol.It is only\r
+  intended to be used by Debug related module implementation.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __PROCESSOR_CONTEXT_H__\r
+#define __PROCESSOR_CONTEXT_H__\r
+\r
+//\r
+//  IA-32/x64 processor register index table\r
+//\r
+#define SOFT_DEBUGGER_REGISTER_DR0      0\r
+#define SOFT_DEBUGGER_REGISTER_DR1      1\r
+#define SOFT_DEBUGGER_REGISTER_DR2      2\r
+#define SOFT_DEBUGGER_REGISTER_DR3      3\r
+#define SOFT_DEBUGGER_REGISTER_DR6      4\r
+#define SOFT_DEBUGGER_REGISTER_DR7      5\r
+#define SOFT_DEBUGGER_REGISTER_EFLAGS   6\r
+#define SOFT_DEBUGGER_REGISTER_LDTR     7\r
+#define SOFT_DEBUGGER_REGISTER_TR       8\r
+#define SOFT_DEBUGGER_REGISTER_GDTR0    9  // the low 32bit of GDTR\r
+#define SOFT_DEBUGGER_REGISTER_GDTR1   10 // the high 32bit of GDTR\r
+#define SOFT_DEBUGGER_REGISTER_IDTR0   11 // the low 32bit of IDTR\r
+#define SOFT_DEBUGGER_REGISTER_IDTR1   12 // the high 32bot of IDTR\r
+#define SOFT_DEBUGGER_REGISTER_EIP     13\r
+#define SOFT_DEBUGGER_REGISTER_GS      14\r
+#define SOFT_DEBUGGER_REGISTER_FS      15\r
+#define SOFT_DEBUGGER_REGISTER_ES      16\r
+#define SOFT_DEBUGGER_REGISTER_DS      17\r
+#define SOFT_DEBUGGER_REGISTER_CS      18\r
+#define SOFT_DEBUGGER_REGISTER_SS      19\r
+#define SOFT_DEBUGGER_REGISTER_CR0     20\r
+#define SOFT_DEBUGGER_REGISTER_CR1     21\r
+#define SOFT_DEBUGGER_REGISTER_CR2     22\r
+#define SOFT_DEBUGGER_REGISTER_CR3     23\r
+#define SOFT_DEBUGGER_REGISTER_CR4     24\r
+\r
+#define SOFT_DEBUGGER_REGISTER_DI      25\r
+#define SOFT_DEBUGGER_REGISTER_SI      26\r
+#define SOFT_DEBUGGER_REGISTER_BP      27\r
+#define SOFT_DEBUGGER_REGISTER_SP      28\r
+#define SOFT_DEBUGGER_REGISTER_DX      29\r
+#define SOFT_DEBUGGER_REGISTER_CX      30\r
+#define SOFT_DEBUGGER_REGISTER_BX      31\r
+#define SOFT_DEBUGGER_REGISTER_AX      32\r
+\r
+//\r
+// This below registers are only available for x64 (not valid for Ia32 mode)\r
+//\r
+#define SOFT_DEBUGGER_REGISTER_CR8     33\r
+#define SOFT_DEBUGGER_REGISTER_R8      34\r
+#define SOFT_DEBUGGER_REGISTER_R9      35\r
+#define SOFT_DEBUGGER_REGISTER_R10     36\r
+#define SOFT_DEBUGGER_REGISTER_R11     37\r
+#define SOFT_DEBUGGER_REGISTER_R12     38\r
+#define SOFT_DEBUGGER_REGISTER_R13     39\r
+#define SOFT_DEBUGGER_REGISTER_R14     40\r
+#define SOFT_DEBUGGER_REGISTER_R15     41\r
+\r
+#define SOFT_DEBUGGER_REGISTER_MAX_COUNT_IA32     33\r
+#define SOFT_DEBUGGER_REGISTER_MAX_COUNT_X64      42\r
+\r
+//\r
+// This below registers are FP / MMX / XMM registers\r
+//\r
+#define SOFT_DEBUGGER_REGISTER_FP_BASE            50\r
+\r
+#define SOFT_DEBUGGER_REGISTER_FP_FCW          (SOFT_DEBUGGER_REGISTER_FP_BASE +  0)\r
+#define SOFT_DEBUGGER_REGISTER_FP_FSW          (SOFT_DEBUGGER_REGISTER_FP_BASE +  1)\r
+#define SOFT_DEBUGGER_REGISTER_FP_FTW          (SOFT_DEBUGGER_REGISTER_FP_BASE +  2)\r
+#define SOFT_DEBUGGER_REGISTER_FP_OPCODE       (SOFT_DEBUGGER_REGISTER_FP_BASE +  3)\r
+#define SOFT_DEBUGGER_REGISTER_FP_EIP          (SOFT_DEBUGGER_REGISTER_FP_BASE +  4)\r
+#define SOFT_DEBUGGER_REGISTER_FP_CS           (SOFT_DEBUGGER_REGISTER_FP_BASE +  5)\r
+#define SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET   (SOFT_DEBUGGER_REGISTER_FP_BASE +  6)\r
+#define SOFT_DEBUGGER_REGISTER_FP_DS           (SOFT_DEBUGGER_REGISTER_FP_BASE +  7)\r
+#define SOFT_DEBUGGER_REGISTER_FP_MXCSR        (SOFT_DEBUGGER_REGISTER_FP_BASE +  8)\r
+#define SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK   (SOFT_DEBUGGER_REGISTER_FP_BASE +  9)\r
+#define SOFT_DEBUGGER_REGISTER_ST0             (SOFT_DEBUGGER_REGISTER_FP_BASE + 10)\r
+#define SOFT_DEBUGGER_REGISTER_ST1             (SOFT_DEBUGGER_REGISTER_FP_BASE + 11)\r
+#define SOFT_DEBUGGER_REGISTER_ST2             (SOFT_DEBUGGER_REGISTER_FP_BASE + 12)\r
+#define SOFT_DEBUGGER_REGISTER_ST3             (SOFT_DEBUGGER_REGISTER_FP_BASE + 13)\r
+#define SOFT_DEBUGGER_REGISTER_ST4             (SOFT_DEBUGGER_REGISTER_FP_BASE + 14)\r
+#define SOFT_DEBUGGER_REGISTER_ST5             (SOFT_DEBUGGER_REGISTER_FP_BASE + 15)\r
+#define SOFT_DEBUGGER_REGISTER_ST6             (SOFT_DEBUGGER_REGISTER_FP_BASE + 16)\r
+#define SOFT_DEBUGGER_REGISTER_ST7             (SOFT_DEBUGGER_REGISTER_FP_BASE + 17)\r
+#define SOFT_DEBUGGER_REGISTER_XMM0            (SOFT_DEBUGGER_REGISTER_FP_BASE + 18)\r
+#define SOFT_DEBUGGER_REGISTER_XMM1            (SOFT_DEBUGGER_REGISTER_FP_BASE + 19)\r
+#define SOFT_DEBUGGER_REGISTER_XMM2            (SOFT_DEBUGGER_REGISTER_FP_BASE + 20)\r
+#define SOFT_DEBUGGER_REGISTER_XMM3            (SOFT_DEBUGGER_REGISTER_FP_BASE + 21)\r
+#define SOFT_DEBUGGER_REGISTER_XMM4            (SOFT_DEBUGGER_REGISTER_FP_BASE + 22)\r
+#define SOFT_DEBUGGER_REGISTER_XMM5            (SOFT_DEBUGGER_REGISTER_FP_BASE + 23)\r
+#define SOFT_DEBUGGER_REGISTER_XMM6            (SOFT_DEBUGGER_REGISTER_FP_BASE + 24)\r
+#define SOFT_DEBUGGER_REGISTER_XMM7            (SOFT_DEBUGGER_REGISTER_FP_BASE + 25)\r
+#define SOFT_DEBUGGER_REGISTER_XMM8            (SOFT_DEBUGGER_REGISTER_FP_BASE + 26)\r
+#define SOFT_DEBUGGER_REGISTER_XMM9            (SOFT_DEBUGGER_REGISTER_FP_BASE + 27)\r
+#define SOFT_DEBUGGER_REGISTER_XMM10           (SOFT_DEBUGGER_REGISTER_FP_BASE + 28)\r
+#define SOFT_DEBUGGER_REGISTER_XMM11           (SOFT_DEBUGGER_REGISTER_FP_BASE + 29)\r
+#define SOFT_DEBUGGER_REGISTER_XMM12           (SOFT_DEBUGGER_REGISTER_FP_BASE + 30)\r
+#define SOFT_DEBUGGER_REGISTER_XMM13           (SOFT_DEBUGGER_REGISTER_FP_BASE + 31)\r
+#define SOFT_DEBUGGER_REGISTER_XMM14           (SOFT_DEBUGGER_REGISTER_FP_BASE + 32)\r
+#define SOFT_DEBUGGER_REGISTER_XMM15           (SOFT_DEBUGGER_REGISTER_FP_BASE + 33)\r
+#define SOFT_DEBUGGER_REGISTER_MM0             (SOFT_DEBUGGER_REGISTER_FP_BASE + 34)\r
+#define SOFT_DEBUGGER_REGISTER_MM1             (SOFT_DEBUGGER_REGISTER_FP_BASE + 35)\r
+#define SOFT_DEBUGGER_REGISTER_MM2             (SOFT_DEBUGGER_REGISTER_FP_BASE + 36)\r
+#define SOFT_DEBUGGER_REGISTER_MM3             (SOFT_DEBUGGER_REGISTER_FP_BASE + 37)\r
+#define SOFT_DEBUGGER_REGISTER_MM4             (SOFT_DEBUGGER_REGISTER_FP_BASE + 38)\r
+#define SOFT_DEBUGGER_REGISTER_MM5             (SOFT_DEBUGGER_REGISTER_FP_BASE + 39)\r
+#define SOFT_DEBUGGER_REGISTER_MM6             (SOFT_DEBUGGER_REGISTER_FP_BASE + 40)\r
+#define SOFT_DEBUGGER_REGISTER_MM7             (SOFT_DEBUGGER_REGISTER_FP_BASE + 41)\r
+\r
+//\r
+// This below registers are for GDT, LDT, TSS\r
+//\r
+#define SOFT_DEBUGGER_REGISTER_OTHERS_BASE            100\r
+\r
+#define SOFT_DEBUGGER_REGISTER_CS_LIM          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  0)\r
+#define SOFT_DEBUGGER_REGISTER_SS_LIM          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  1)\r
+#define SOFT_DEBUGGER_REGISTER_GS_LIM          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  2)\r
+#define SOFT_DEBUGGER_REGISTER_FS_LIM          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  3)\r
+#define SOFT_DEBUGGER_REGISTER_ES_LIM          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  4)\r
+#define SOFT_DEBUGGER_REGISTER_DS_LIM          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  5)\r
+#define SOFT_DEBUGGER_REGISTER_LDT_LIM          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE + 6)\r
+#define SOFT_DEBUGGER_REGISTER_TSS_LIM          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE + 7)\r
+\r
+#define SOFT_DEBUGGER_REGISTER_CS_BAS          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  8)\r
+#define SOFT_DEBUGGER_REGISTER_SS_BAS          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  9)\r
+#define SOFT_DEBUGGER_REGISTER_GS_BAS          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  10)\r
+#define SOFT_DEBUGGER_REGISTER_FS_BAS          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  11)\r
+#define SOFT_DEBUGGER_REGISTER_ES_BAS          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  12)\r
+#define SOFT_DEBUGGER_REGISTER_DS_BAS          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  13)\r
+#define SOFT_DEBUGGER_REGISTER_LDT_BAS         (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  14)\r
+#define SOFT_DEBUGGER_REGISTER_TSS_BAS         (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  15)\r
+\r
+#define SOFT_DEBUGGER_REGISTER_CSAS            (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  16)\r
+#define SOFT_DEBUGGER_REGISTER_SSAS            (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  17)\r
+#define SOFT_DEBUGGER_REGISTER_GSAS            (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  18)\r
+#define SOFT_DEBUGGER_REGISTER_FSAS            (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  19)\r
+#define SOFT_DEBUGGER_REGISTER_ESAS            (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  20)\r
+#define SOFT_DEBUGGER_REGISTER_DSAS            (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  21)\r
+#define SOFT_DEBUGGER_REGISTER_LDTAS           (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  22)\r
+#define SOFT_DEBUGGER_REGISTER_TSSAS           (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  23)\r
+\r
+#define SOFT_DEBUGGER_REGISTER_IDT_LIM          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE + 24)\r
+#define SOFT_DEBUGGER_REGISTER_GDT_LIM          (SOFT_DEBUGGER_REGISTER_OTHERS_BASE + 25)\r
+#define SOFT_DEBUGGER_REGISTER_IDT_BAS         (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  26)\r
+#define SOFT_DEBUGGER_REGISTER_GDT_BAS         (SOFT_DEBUGGER_REGISTER_OTHERS_BASE +  27)\r
+\r
+\r
+#define SOFT_DEBUGGER_MSR_EFER                (0xC0000080)\r
+\r
+//\r
+// Definition for the Index field for DEBUG_DATA_READ_REGISTER_GROUP\r
+//\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_GPDRS32                1 //for cs,ds,es,fs,gs,ss,eflags,ebp,eip,esp,eax,ebx,ecx,edx,esi,edi,dr0,dr1,dr2,dr3,dr6,dr7\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_LIMITS32       2 //for cslim,sslim,gslim,fslim,eslim,dslim,ldtlim,tsslim\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_BASES32        3 //for csbas,ssbas,gsbas,fsbas,esbas,dsbas,ldtbas,tssbas\r
+\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT64              4  //for cs,ds,es,fs,gs,ss\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_GP2_64                 5  //for eflags,rbp,rip,rsp\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_GP64                   6  //for rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_DR64                   7  //for dr0,dr1,dr2,dr3,dr6,dr7\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_BAS_LIM64      8  //for ldtbas,ldtlim,gdtbas,gdtlim,cslim,sslim,gslim,fslim,eslim,dslim,ldtlim,tsslim,csbas,ssbas,gsbas,fsbas,esbas,dsbas,ldtbas,tssbas\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_BASES64        9  //for idtr,tr,csas,ssas,gsas,fsas,esas,dsas,idtas,tssas\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_CR64                   10 //for cr0,cr2,cr3,cr4,cr8\r
+#define SOFT_DEBUGGER_REGISTER_GROUP_XMM64                  11 //for xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15\r
+\r
+\r
+#endif\r
+\r
diff --git a/SourceLevelDebugPkg/Include/ImageDebugSupport.h b/SourceLevelDebugPkg/Include/ImageDebugSupport.h
new file mode 100644 (file)
index 0000000..6829985
--- /dev/null
@@ -0,0 +1,27 @@
+/** @file\r
+  Public include file for Debug Agent Library instance and PE/COFF Extra\r
+  Action Library instance.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __IMAGE_DEBUG_SUPPORT_H__\r
+#define __IMAGE_DEBUG_SUPPORT_H__\r
+\r
+#define IO_PORT_BREAKPOINT_ADDRESS  0x84\r
+#define IMAGE_LOAD_SIGNATURE        SIGNATURE_32('L','O','A','D')\r
+#define IMAGE_UNLOAD_SIGNATURE      SIGNATURE_32('U','N','L','O')\r
+\r
+#define DEBUG_AGENT_IMAGE_WAIT      0x00\r
+#define DEBUG_AGENT_IMAGE_CONTINUE  0x01\r
+\r
+#endif\r
+\r
diff --git a/SourceLevelDebugPkg/Include/Library/DebugCommunicationLib.h b/SourceLevelDebugPkg/Include/Library/DebugCommunicationLib.h
new file mode 100644 (file)
index 0000000..8fc0aa7
--- /dev/null
@@ -0,0 +1,152 @@
+/** @file\r
+  Debug Communication Library definitions.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __DEBUG_COMMUNICATION_LIB_H__\r
+#define __DEBUG_COMMUNICATION_LIB_H__\r
+\r
+typedef VOID *    DEBUG_PORT_HANDLE;\r
+\r
+/**\r
+  Caller provided function to be invoked at the end of DebugPortInitialize().\r
+\r
+  Refer to the descrption for DebugPortInitialize() for more details.\r
+\r
+  @param[in] Context           The first input argument of DebugPortInitialize().\r
+  @param[in] DebugPortHandle   Debug port handle created by Debug Communication Libary.\r
+\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI * DEBUG_PORT_CONTINUE)(\r
+  IN VOID                *Context,\r
+  IN DEBUG_PORT_HANDLE   DebugPortHandle\r
+  );\r
+\r
+/**\r
+  Initialize the debug port.\r
+\r
+  This function will initialize debug port to get it ready for data transmition. If\r
+  certain Debug Communication Library instance has to save some private data in the\r
+  stack, this function must work on the mode that doesn't return to the caller, then\r
+  the caller needs to wrap up all rest of logic after DebugPortInitialize() into one\r
+  function and pass it into DebugPortInitialize(). DebugPortInitialize() is\r
+  responsible to invoke the passing-in funciton at the end of DebugPortInitialize().\r
+\r
+  If the paramter Function is not NULL, Debug Communication Libary instance will\r
+  invoke it by passing in the Context to be the first parameter. Debug Communication\r
+  Library instance could create one debug port handle to be the second parameter\r
+  passing into the Function. Debug Communication Library instance also could pass\r
+  NULL to be the second parameter if it doesn't create the debug port handle.\r
+\r
+  If the parameter Function is NULL, and Context is not NULL. At this time, Context\r
+  is the debug port handle created by the previous Debug Communication Library\r
+  instance.\r
+  a) If the instance can understand and continue use the private data of the previous\r
+     instance, it could return the same handle as passed in (as Context parameter).\r
+  b) If the instance does not understand, or does not want to continue use the\r
+     private data of the previous instance, it could ignore the input Context parameter\r
+     and create the new hanlde to be returned.\r
+\r
+  If Function() is NULL and Context is NULL, Debug Communication Library could create a\r
+  new handle and return it. NULL is also a valid handle to be returned.\r
+\r
+  @param[in] Context      Context needed by callback function; it was optional.\r
+  @param[in] Function     Continue function called by Debug Communication library;\r
+                          it was optional.\r
+\r
+  @return  The debug port handle created by Debug Communication Library if Function\r
+           is not NULL.\r
+\r
+**/\r
+DEBUG_PORT_HANDLE\r
+EFIAPI\r
+DebugPortInitialize (\r
+  IN VOID                 *Context,\r
+  IN DEBUG_PORT_CONTINUE  Function\r
+  );\r
+\r
+\r
+/**\r
+  Read data from debug device and save the datas in buffer.\r
+\r
+  Reads NumberOfBytes data bytes from a debug device into the buffer\r
+  specified by Buffer. The number of bytes actually read is returned.\r
+  If the return value is less than NumberOfBytes, then the rest operation failed.\r
+  If NumberOfBytes is zero, then return 0.\r
+\r
+  @param  Handle           Debug port handle.\r
+  @param  Buffer           Pointer to the data buffer to store the data read from the debug device.\r
+  @param  NumberOfBytes    Number of bytes which will be read.\r
+  @param  Timeout          Timeout value for reading from debug device. It unit is Microsecond.\r
+\r
+  @retval 0                Read data failed, no data is to be read.\r
+  @retval >0               Actual number of bytes read from debug device.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+DebugPortReadBuffer (\r
+  IN DEBUG_PORT_HANDLE     Handle,\r
+  IN UINT8                 *Buffer,\r
+  IN UINTN                 NumberOfBytes,\r
+  IN UINTN                 Timeout\r
+  );\r
+\r
+\r
+/**\r
+  Write data from buffer to debug device.\r
+\r
+  Writes NumberOfBytes data bytes from Buffer to the debug device.\r
+  The number of bytes actually written to the debug device is returned.\r
+  If the return value is less than NumberOfBytes, then the write operation failed.\r
+  If NumberOfBytes is zero, then return 0.\r
+\r
+  @param  Handle           Debug port handle.\r
+  @param  Buffer           Pointer to the data buffer to be written.\r
+  @param  NumberOfBytes    Number of bytes to written to the debug device.\r
+\r
+  @retval 0                NumberOfBytes is 0.\r
+  @retval >0               The number of bytes written to the debug device.\r
+                           If this value is less than NumberOfBytes, then the read operation failed.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+DebugPortWriteBuffer (\r
+  IN DEBUG_PORT_HANDLE     Handle,\r
+  IN UINT8                 *Buffer,\r
+  IN UINTN                 NumberOfBytes\r
+  );\r
+\r
+/**\r
+  Polls a debug device to see if there is any data waiting to be read.\r
+\r
+  Polls a debug device to see if there is any data waiting to be read.\r
+  If there is data waiting to be read from the debug device, then TRUE is returned.\r
+  If there is no data waiting to be read from the debug device, then FALSE is returned.\r
+\r
+  @param  Handle           Debug port handle.\r
+\r
+  @retval TRUE             Data is waiting to be read from the debug device.\r
+  @retval FALSE            There is no data waiting to be read from the serial device.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugPortPollBuffer (\r
+  IN DEBUG_PORT_HANDLE     Handle\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/SourceLevelDebugPkg/Include/SoftDebuggerDefinitions.h b/SourceLevelDebugPkg/Include/SoftDebuggerDefinitions.h
new file mode 100644 (file)
index 0000000..4e2b638
--- /dev/null
@@ -0,0 +1,42 @@
+/** @file\r
+  Soft Debugger defintions. The definitions will also be used as part\r
+  of debug transfer protocol. It is only intended to be used by Debug\r
+  related module implementation.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __SOFT_DEBUGGER_DEFINITIONS_H__\r
+#define __SOFT_DEBUGGER_DEFINITIONS_H__\r
+\r
+//\r
+// Definition for processor mode (IA16, IA32, X64, ...)\r
+//\r
+#define SOFT_DEBUGGER_PROCESSOR_IA16        0\r
+#define SOFT_DEBUGGER_PROCESSOR_IA32        1\r
+#define SOFT_DEBUGGER_PROCESSOR_X64         2\r
+\r
+//\r
+// Break cause defintions\r
+//\r
+#define SOFT_DEBUGGER_BREAK_CAUSE_UNKNOWN        0\r
+#define SOFT_DEBUGGER_BREAK_CAUSE_HW_BREAKPOINT  1\r
+#define SOFT_DEBUGGER_BREAK_CAUSE_STEPPING       2\r
+#define SOFT_DEBUGGER_BREAK_CAUSE_SW_BREAKPOINT  3\r
+#define SOFT_DEBUGGER_BREAK_CAUSE_USER_HALT      4\r
+#define SOFT_DEBUGGER_BREAK_CAUSE_IMAGE_LOAD     5\r
+#define SOFT_DEBUGGER_BREAK_CAUSE_IMAGE_UNLOAD   6\r
+#define SOFT_DEBUGGER_BREAK_CAUSE_SYSTEM_RESET   7\r
+#define SOFT_DEBUGGER_BREAK_CAUSE_EXCEPTION      8\r
+\r
+#define SOFT_DEBUGGER_SETTING_SMM_ENTRY_BREAK    1\r
+\r
+#endif\r
diff --git a/SourceLevelDebugPkg/Include/TransferProtocol.h b/SourceLevelDebugPkg/Include/TransferProtocol.h
new file mode 100644 (file)
index 0000000..b7e1143
--- /dev/null
@@ -0,0 +1,407 @@
+/** @file\r
+  Transfer protocol defintions used by debug agent and host. It is only\r
+  intended to be used by Debug related module implementation.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __TRANSFER_PROTOCOL_H__\r
+#define __TRANSFER_PROTOCOL_H__\r
+\r
+#include "ProcessorContext.h"\r
+#include "SoftDebuggerDefinitions.h"\r
+\r
+//\r
+// Definitions for break command.\r
+//\r
+#define DEBUG_STARTING_SYMBOL_BREAK     (0x21)  //  '!'\r
+#define DEBUG_STARTING_SYMBOL_BREAK_STRING     ("!")\r
+\r
+//\r
+//  Definition for starting symbol of a normal debug packet. Choose a non-ASCII to avoid conflict with other serial output.\r
+//\r
+#define DEBUG_STARTING_SYMBOL_NORMAL    (0xFE)\r
+\r
+\r
+#pragma pack(1)\r
+\r
+//\r
+// Definition for common header for normal debug packets (not including break command)\r
+//\r
+typedef struct {\r
+  UINT8                      StartSymbol;\r
+  UINT8                      Command;\r
+  UINT8                      DataLength;\r
+} DEBUG_COMMAND_HEADER;\r
+\r
+//\r
+// Structure to facilitate debug packet header parsing or construction\r
+//\r
+typedef struct {\r
+  UINT8                      Command;\r
+  UINT8                      DataLength;\r
+} DEBUG_COMMAND_HEADER_NO_START_SYMBOL;\r
+\r
+\r
+//\r
+// Definition for Command field for debug packets\r
+//\r
+#define DEBUG_COMMAND_REQUEST      (0 << 7)\r
+#define DEBUG_COMMAND_RESPONSE     (1 << 7)\r
+\r
+\r
+\r
+#define DEBUG_COMMAND_RESET                       (DEBUG_COMMAND_REQUEST | 0)  // 0\r
+\r
+#define DEBUG_COMMAND_GO                          (DEBUG_COMMAND_REQUEST | 1)  // 1\r
+\r
+#define DEBUG_COMMAND_BREAK_CAUSE                 (DEBUG_COMMAND_REQUEST | 2)  // 2\r
+\r
+#define DEBUG_COMMAND_SET_HW_BREAKPOINT           (DEBUG_COMMAND_REQUEST | 3)  // 3\r
+#define DEBUG_COMMAND_CLEAR_HW_BREAKPOINT         (DEBUG_COMMAND_REQUEST | 4)  // 4\r
+\r
+#define DEBUG_COMMAND_SINGLE_STEPPING             (DEBUG_COMMAND_REQUEST | 5)  // 5\r
+\r
+#define DEBUG_COMMAND_SET_SW_BREAKPOINT           (DEBUG_COMMAND_REQUEST | 6)  // 6\r
+#define DEBUG_COMMAND_CLEAR_SW_BREAKPOINT         (DEBUG_COMMAND_REQUEST | 7)  // 7\r
+\r
+#define DEBUG_COMMAND_READ_MEMORY_8               (DEBUG_COMMAND_REQUEST | 8)  // 8\r
+#define DEBUG_COMMAND_READ_MEMORY_16              (DEBUG_COMMAND_REQUEST | 9)  // 9\r
+#define DEBUG_COMMAND_READ_MEMORY_32              (DEBUG_COMMAND_REQUEST | 10) // 10\r
+#define DEBUG_COMMAND_READ_MEMORY_64              (DEBUG_COMMAND_REQUEST | 11) // 11\r
+\r
+#define DEBUG_COMMAND_WRITE_MEMORY_8              (DEBUG_COMMAND_REQUEST | 12) // 12\r
+#define DEBUG_COMMAND_WRITE_MEMORY_16             (DEBUG_COMMAND_REQUEST | 13) // 13\r
+#define DEBUG_COMMAND_WRITE_MEMORY_32             (DEBUG_COMMAND_REQUEST | 14) // 14\r
+#define DEBUG_COMMAND_WRITE_MEMORY_64             (DEBUG_COMMAND_REQUEST | 15) // 15\r
+\r
+#define DEBUG_COMMAND_READ_IO                     (DEBUG_COMMAND_REQUEST | 16) // 16\r
+#define DEBUG_COMMAND_WRITE_IO                    (DEBUG_COMMAND_REQUEST | 20) // 20\r
+\r
+#define DEBUG_COMMAND_READ_REGISTER               (DEBUG_COMMAND_REQUEST | 24) // 24\r
+#define DEBUG_COMMAND_WRITE_REGISTER              (DEBUG_COMMAND_REQUEST | 26) // 26\r
+\r
+#define DEBUG_COMMAND_STEP_OVER                   (DEBUG_COMMAND_REQUEST | 28) // 28\r
+#define DEBUG_COMMAND_STEP_OUT                    (DEBUG_COMMAND_REQUEST | 29) // 29\r
+#define DEBUG_COMMAND_STEP_BRANCH                 (DEBUG_COMMAND_REQUEST | 30) // 30\r
+\r
+#define DEBUG_COMMAND_ARCH_MODE                   (DEBUG_COMMAND_REQUEST | 34) // 34\r
+\r
+#define DEBUG_COMMAND_READ_MSR                    (DEBUG_COMMAND_REQUEST | 35) // 35\r
+#define DEBUG_COMMAND_WRITE_MSR                   (DEBUG_COMMAND_REQUEST | 36) // 36\r
+\r
+#define DEBUG_COMMAND_READ_REGISTER_GROUP         (DEBUG_COMMAND_REQUEST | 37) // 37\r
+\r
+#define DEBUG_COMMAND_SET_DEBUG_FLAG              (DEBUG_COMMAND_REQUEST | 38) // 38\r
+\r
+#define DEBUG_COMMAND_GET_REVISION                (DEBUG_COMMAND_REQUEST | 39) // 30\r
+\r
+#define DEBUG_COMMAND_GET_EXCEPTION               (DEBUG_COMMAND_REQUEST | 40) // 40\r
+\r
+#define DEBUG_COMMAND_SET_VIEWPOINT               (DEBUG_COMMAND_REQUEST | 41) // 41\r
+\r
+#define DEBUG_COMMAND_GET_VIEWPOINT               (DEBUG_COMMAND_REQUEST | 42) // 42\r
+\r
+//\r
+// The below are target side initiated commands.\r
+//\r
+#define DEBUG_COMMAND_INIT_BREAK                  (DEBUG_COMMAND_REQUEST | 63) // 63\r
+#define DEBUG_COMMAND_BREAK_POINT                 (DEBUG_COMMAND_REQUEST | 62) // 62\r
+#define DEBUG_COMMAND_MEMORY_READY                (DEBUG_COMMAND_REQUEST | 61) // 61\r
+\r
+#define DEBUG_COMMAND_OK                          (DEBUG_COMMAND_RESPONSE | 0)\r
+#define DEBUG_COMMAND_RESEND                      (DEBUG_COMMAND_RESPONSE | 1)\r
+#define DEBUG_COMMAND_ABORT                       (DEBUG_COMMAND_RESPONSE | 2)\r
+\r
+//\r
+// The below 2 commands are used when transferring big data (like > ~250 bytes). The sequence is:\r
+//  Host Macine                      Target Macine\r
+//  Request                =>\r
+//                         <=        IN_PROGRESS with part of the data\r
+//  CONTINUE               =>\r
+//  (could have multiple IN_PROGRESS and CONTINUE interactions)\r
+//                         <=        OK with the last part of data\r
+//  OK (no data as ACK)    =>\r
+//\r
+#define DEBUG_COMMAND_IN_PROGRESS                 (DEBUG_COMMAND_RESPONSE | 3)  // Used when trying to\r
+#define DEBUG_COMMAND_CONTINUE                    (DEBUG_COMMAND_RESPONSE | 4)  // Used when trying to transfer big data (like > ~250 bytes)\r
+\r
+//\r
+// The below 2 commands are used to support deferred halt. HALT_DEFERRED will be returned when a halt request received while target is already in inter-active mode.\r
+// HALT_PROCESSED will be return as a possible return value for GO command, if target has a pending halt request.\r
+//\r
+#define DEBUG_COMMAND_HALT_DEFERRED               (DEBUG_COMMAND_RESPONSE | 5)\r
+#define DEBUG_COMMAND_HALT_PROCESSED              (DEBUG_COMMAND_RESPONSE | 6)\r
+\r
+#define DEBUG_COMMAND_NOT_SUPPORTED               (DEBUG_COMMAND_RESPONSE | 15)\r
+\r
+//\r
+// Definition for data field for debug packets\r
+//\r
+#define DEBUG_DATA_MAXIMUM_LENGTH_FOR_SMALL_COMMANDS     20\r
+\r
+#define DEBUG_DATA_UPPER_LIMIT                           0xff  // This is the upper limit for the data size, by the limit of the packet header definition.\r
+\r
+#define DEBUG_DATA_MAXIMUM_REAL_DATA                     0xf8\r
+\r
+#define DEBUG_DEFINITION_MAX_IO_LENGTH                   4\r
+\r
+//\r
+// Response data for DEBUG_COMMAND_BREAK_CAUSE\r
+//\r
+typedef struct {\r
+  UINT8       Cause;\r
+  UINT64      StopAddress;\r
+} DEBUG_DATA_RESPONSE_BREAK_CAUSE;\r
+\r
+//\r
+// Break type defintions for DEBUG_DATA_BREAK_CAUSE\r
+//\r
+#define DEBUG_DATA_BREAK_CAUSE_UNKNOWN        0\r
+#define DEBUG_DATA_BREAK_CAUSE_HW_BREAKPOINT  1\r
+#define DEBUG_DATA_BREAK_CAUSE_STEPPING       2\r
+#define DEBUG_DATA_BREAK_CAUSE_SW_BREAKPOINT  3\r
+#define DEBUG_DATA_BREAK_CAUSE_USER_HALT      4\r
+#define DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD     5\r
+#define DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD   6\r
+#define DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET   7\r
+#define DEBUG_DATA_BREAK_CAUSE_EXCEPTION      8\r
+#define DEBUG_DATA_BREAK_CAUSE_MEMORY_READY   9\r
+\r
+//\r
+// Response data for DEBUG_COMMAND_ARCH_MODE, defined as SOFT_DEBUGGER_PROCESSOR_...\r
+//\r
+typedef struct {\r
+  UINT8       CpuMode;\r
+} DEBUG_DATA_RESPONSE_ARCH_MODE;\r
+\r
+//\r
+// Cpu architecture defintions for DEBUG_DATA_RESPONSE_ARCH_MODE\r
+//\r
+#define DEBUG_DATA_BREAK_CPU_ARCH_IA16        0\r
+#define DEBUG_DATA_BREAK_CPU_ARCH_IA32        1\r
+#define DEBUG_DATA_BREAK_CPU_ARCH_X64         2\r
+\r
+//\r
+// Command and response data for DEBUG_COMMAND_XX_YY_BREAKPOINT\r
+//\r
+typedef struct {\r
+  UINT8  Length:2;                   // Refer to below DEBUG_DATA_BREAKPOINT_LENGTH_XX macros\r
+  UINT8  Access:2;                   // Refer to below DEBUG_DATA_BREAKPOINT_ACCESS_XX macros\r
+  UINT8  Index:2;                    // Index of debug register\r
+  UINT8  Reserved:2;\r
+} DEBUG_DATA_BREAKPOINT_TYPE;\r
+\r
+#define DEBUG_DATA_BREAKPOINT_MEMORY_ACCESS    (0x11)\r
+#define DEBUG_DATA_BREAKPOINT_IO_ACCESS        (0x10)\r
+#define DEBUG_DATA_BREAKPOINT_MEMORY_WRITE     (0x01)\r
+#define DEBUG_DATA_BREAKPOINT_MEMORY_EXECUTE   (0x00)\r
+\r
+#define DEBUG_DATA_BREAKPOINT_LENGTH_64        (0x11)\r
+#define DEBUG_DATA_BREAKPOINT_LENGTH_32        (0x10)\r
+#define DEBUG_DATA_BREAKPOINT_LENGTH_16        (0x01)\r
+#define DEBUG_DATA_BREAKPOINT_LENGTH_8         (0x00)\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_SET_HW_BREAKPOINT\r
+//\r
+typedef struct {\r
+  DEBUG_DATA_BREAKPOINT_TYPE Type;\r
+  UINT64                     Address;\r
+} DEBUG_DATA_SET_HW_BREAKPOINT;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_CLEAR_HW_BREAKPOINT\r
+//\r
+typedef struct {\r
+  UINT8                      IndexMask;  // 0x0f will clear all hw breakpoints\r
+} DEBUG_DATA_CLEAR_HW_BREAKPOINT;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_SET_SW_BREAKPOINT\r
+//\r
+typedef struct {\r
+  UINT64                     Address;\r
+} DEBUG_DATA_SET_SW_BREAKPOINT;\r
+\r
+//\r
+// Response data for DEBUG_COMMAND_SET_SW_BREAKPOINT\r
+//\r
+typedef struct {\r
+  UINT8                      OriginalData;\r
+} DEBUG_DATA_RESPONSE_SET_SW_BREAKPOINT;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_CLEAR_SW_BREAKPOINT\r
+//\r
+typedef  DEBUG_DATA_SET_SW_BREAKPOINT DEBUG_DATA_CLEAR_SW_BREAKPOINT;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_READ_MEMORY_XX\r
+//\r
+typedef struct {\r
+  UINT64                     Address;\r
+  UINT16                     Count;\r
+} DEBUG_DATA_READ_MEMORY_8;\r
+\r
+typedef DEBUG_DATA_READ_MEMORY_8 DEBUG_DATA_READ_MEMORY_16;\r
+\r
+typedef DEBUG_DATA_READ_MEMORY_8 DEBUG_DATA_READ_MEMORY_32;\r
+\r
+typedef DEBUG_DATA_READ_MEMORY_8 DEBUG_DATA_READ_MEMORY_64;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_WRITE_MEMORY_XX\r
+//\r
+typedef struct {\r
+  UINT64                     Address;\r
+  UINT16                     Count;\r
+  UINT8                      Data;     // The actual length for this field is decided by Width x Count\r
+} DEBUG_DATA_WRITE_MEMORY_8;\r
+\r
+typedef DEBUG_DATA_WRITE_MEMORY_8 DEBUG_DATA_WRITE_MEMORY_16;\r
+\r
+typedef DEBUG_DATA_WRITE_MEMORY_8 DEBUG_DATA_WRITE_MEMORY_32;\r
+\r
+typedef DEBUG_DATA_WRITE_MEMORY_8 DEBUG_DATA_WRITE_MEMORY_64;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_READ_IO\r
+//\r
+typedef struct {\r
+  UINT16                     Port;\r
+  UINT8                      Width;\r
+} DEBUG_DATA_READ_IO;\r
+\r
+//\r
+// Response data for DEBUG_COMMAND_READ_IO\r
+//\r
+typedef struct {\r
+  UINT8                      Data;  // The actual length of this structure will be adjusted according to the Width field\r
+} DEBUG_DATA_RESPONSE_READ_IO;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_WRITE_IO\r
+//\r
+typedef struct {\r
+  UINT16                     Port;\r
+  UINT8                      Width;\r
+  UINT8                      Data; // The actual length of this structure will be adjusted according to the Width field\r
+} DEBUG_DATA_WRITE_IO;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_READ_REGISTER\r
+//\r
+typedef struct {\r
+  UINT8                      Index;   // defined as DEBUG_DEFINITION_REGISTER_XX\r
+  UINT8                      Offset:4;\r
+  UINT8                      Length:4;\r
+} DEBUG_DATA_READ_REGISTER;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_WRITE_REGISTER\r
+//\r
+typedef struct {\r
+  UINT8                      Index;   // defined as DEBUG_DEFINITION_REGISTER_XX\r
+  UINT8                      Offset:4;\r
+  UINT8                      Length:4;\r
+  UINT64                     Value;\r
+} DEBUG_DATA_WRITE_REGISTER;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_READ_MSR\r
+//\r
+typedef struct {\r
+  UINT32                     Index;\r
+} DEBUG_DATA_READ_MSR;\r
+\r
+//\r
+// Response data for DEBUG_COMMAND_READ_MSR\r
+//\r
+typedef struct {\r
+  UINT64                     Value;\r
+} DEBUG_DATA_RESPONSE_READ_MSR;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_WRITE_MSR\r
+//\r
+typedef struct {\r
+  UINT32                     Index;\r
+  UINT64                     Value;\r
+} DEBUG_DATA_WRITE_MSR;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_READ_REGISTER_GROUP\r
+//\r
+typedef struct {\r
+  // For possible values, refer to the definition for DEBUG_DEFINITION_REGISTER_GROUP_XXX (in another .h file as it is architecture specific)\r
+  UINT8                     Index;\r
+} DEBUG_DATA_READ_REGISTER_GROUP;\r
+\r
+//\r
+// Response data for DEBUG_COMMAND_GET_REVISION\r
+//\r
+typedef struct {\r
+  UINT32                    Revision;\r
+  UINT32                    Capabilities;\r
+} DEBUG_DATA_RESPONSE_GET_REVISION;\r
+\r
+//\r
+// Response data for DEBUG_COMMAND_GET_EXCEPTION\r
+//\r
+typedef struct {\r
+  UINT8                     ExceptionNum;\r
+  UINT64                    ExceptionData;\r
+} DEBUG_DATA_RESPONSE_GET_EXCEPTION;\r
+\r
+typedef struct {\r
+  UINT8                     DRn;    // The index of DR register which to be used as temporary breakpoint\r
+} DEBUG_DATA_STEP_OVER;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_SET_DEBUG_FLAG\r
+//\r
+typedef struct {\r
+  UINT32                    DebugFlag;    // The index of DR register which to be used as temporary breakpoint\r
+} DEBUG_DATA_SET_DEBUG_FLAG;\r
+\r
+//\r
+// Command data for DEBUG_COMMAND_SET_VIEWPOINT\r
+// If viewpoint is changed successfully, DEBUG_COMMAND_OK will be returned.\r
+// If viewpoint is not availabe, DEBUG_COMMAND_NOT_SUPPORTED will be returned.\r
+//\r
+typedef struct {\r
+  UINT32                    ViewPoint;     // The index of viewpoint will be set\r
+} DEBUG_DATA_SET_VIEWPOINT;\r
+\r
+//\r
+// Response data for DEBUG_COMMAND_GET_VIEWPOINT\r
+//\r
+typedef struct {\r
+  UINT32                    ViewPoint;     // The index of viewpoint will be returned\r
+} DEBUG_DATA_RESPONSE_GET_VIEWPOINT;\r
+\r
+#pragma pack()\r
+\r
+#define DEBUG_PACKET_CONSTRUCTOR_WITH_NO_DATA(DebugPacket,ShortCommandType)                              \\r
+  ((DEBUG_COMMAND_HEADER *)DebugPacket)->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;                     \\r
+  ((DEBUG_COMMAND_HEADER *)DebugPacket)->Command = DEBUG_COMMAND_##ShortCommandType;                     \\r
+  ((DEBUG_COMMAND_HEADER *)DebugPacket)->DataLength = 0;\r
+\r
+#define DEBUG_PACKET_CONSTRUCTOR_WITH_DATA(DebugPacket,ShortCommandType, DebugPacketDataPointer, PacketLength)         \\r
+  ((DEBUG_COMMAND_HEADER *)DebugPacket)->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;                     \\r
+  ((DEBUG_COMMAND_HEADER *)DebugPacket)->Command = DEBUG_COMMAND_##ShortCommandType;                     \\r
+  ((DEBUG_COMMAND_HEADER *)DebugPacket)->DataLength = sizeof (DEBUG_DATA_##ShortCommandType);            \\r
+  *DebugPacketDataPointer = (DEBUG_DATA_##ShortCommandType *)((DEBUG_COMMAND_HEADER *)DebugPacket+1);    \\r
+  *PacketLength = sizeof (DEBUG_COMMAND_HEADER) + sizeof (DEBUG_DATA_##ShortCommandType);\r
+\r
+#endif\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c
new file mode 100644 (file)
index 0000000..39b24c3
--- /dev/null
@@ -0,0 +1,1195 @@
+/** @file\r
+  Commond Debug Agent library implementition. It mainly includes\r
+  the first C function called by exception/interrupt handlers,\r
+  read/write debug packet to communication with HOST based on transfer\r
+  protocol.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "DebugAgent.h"\r
+#include "Ia32/DebugException.h"\r
+\r
+/**\r
+  Check if HOST is connected based on Mailbox.\r
+\r
+  @retval TRUE        HOST is connected.\r
+  @retval FALSE       HOST is not connected.\r
+\r
+**/\r
+BOOLEAN\r
+IsHostConnected (\r
+  VOID\r
+  )\r
+{\r
+  DEBUG_AGENT_MAILBOX          *Mailbox;\r
+\r
+  Mailbox = GetMailboxPointer ();\r
+\r
+  if (Mailbox->DebugFlag.Bits.HostPresent == 1) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Set HOST connect flag in Mailbox.\r
+\r
+**/\r
+VOID\r
+SetHostConnectedFlag (\r
+  VOID\r
+  )\r
+{\r
+  DEBUG_AGENT_MAILBOX          *Mailbox;\r
+\r
+  Mailbox = GetMailboxPointer ();\r
+\r
+  Mailbox->DebugFlag.Bits.HostPresent = 1;\r
+}\r
+\r
+/**\r
+  Set debug flag of Debug Agent in Mailbox.\r
+\r
+  @param DebugFlag       Debug Flag defined by transfer protocol.\r
+\r
+**/\r
+VOID\r
+SetDebugFlag (\r
+  IN UINT32               DebugFlag\r
+  )\r
+{\r
+  DEBUG_AGENT_MAILBOX          *Mailbox;\r
+\r
+  Mailbox = GetMailboxPointer ();\r
+\r
+  if ((DebugFlag & SOFT_DEBUGGER_SETTING_SMM_ENTRY_BREAK) != 0) {\r
+    Mailbox->DebugFlag.Bits.BreakOnNextSmi = 1;\r
+  } else {\r
+    Mailbox->DebugFlag.Bits.BreakOnNextSmi = 0;\r
+  }\r
+}\r
+\r
+/**\r
+  Exectue GO command.\r
+\r
+  @param[in] CpuContext        Pointer to saved CPU context.\r
+\r
+**/\r
+VOID\r
+CommandGo (\r
+  IN DEBUG_CPU_CONTEXT         *CpuContext\r
+  )\r
+{\r
+  IA32_EFLAGS32                *Eflags;\r
+\r
+  Eflags = (IA32_EFLAGS32 *) &CpuContext->Eflags;\r
+  Eflags->Bits.TF = 0;\r
+  Eflags->Bits.RF = 1;\r
+}\r
+\r
+/**\r
+  Exectue Stepping command.\r
+\r
+  @param[in] CpuContext        Pointer to saved CPU context.\r
+\r
+**/\r
+VOID\r
+CommandStepping (\r
+  IN DEBUG_CPU_CONTEXT          *CpuContext\r
+  )\r
+{\r
+  IA32_EFLAGS32                *Eflags;\r
+\r
+  Eflags = (IA32_EFLAGS32 *) &CpuContext->Eflags;\r
+  Eflags->Bits.TF = 1;\r
+  Eflags->Bits.RF = 1;\r
+}\r
+\r
+/**\r
+  Set debug register for hardware breakpoint.\r
+\r
+  @param[in] CpuContext      Pointer to saved CPU context.\r
+  @param[in] SetHwBreakpoint Hardware breakpoint to be set.\r
+\r
+**/\r
+VOID\r
+SetDebugRegister (\r
+  IN DEBUG_CPU_CONTEXT             *CpuContext,\r
+  IN DEBUG_DATA_SET_HW_BREAKPOINT  *SetHwBreakpoint\r
+  )\r
+{\r
+  UINT8                      RegisterIndex;\r
+  UINTN                      Dr7Value;\r
+\r
+  RegisterIndex = SetHwBreakpoint->Type.Index;\r
+\r
+  //\r
+  // Set debug address\r
+  //\r
+  * ((UINTN *) &CpuContext->Dr0 + RegisterIndex) = (UINTN) SetHwBreakpoint->Address;\r
+\r
+  Dr7Value = CpuContext->Dr7;\r
+\r
+  //\r
+  // Enable Gx, Lx\r
+  //\r
+  Dr7Value |= 0x3 << (RegisterIndex * 2);\r
+  //\r
+  // Set RWx and Lenx\r
+  //\r
+  Dr7Value &= ~(0xf0000 << (RegisterIndex * 4));\r
+  Dr7Value |= (SetHwBreakpoint->Type.Length | SetHwBreakpoint->Type.Access) << (RegisterIndex * 4);\r
+  //\r
+  // Enable GE, LE\r
+  //\r
+  Dr7Value |= 0x300;\r
+\r
+  CpuContext->Dr7 = Dr7Value;\r
+}\r
+\r
+/**\r
+  Clear debug register for hardware breakpoint.\r
+\r
+  @param[in] CpuContext        Pointer to saved CPU context.\r
+  @param[in] ClearHwBreakpoint Hardware breakpoint to be cleared.\r
+\r
+**/\r
+VOID\r
+ClearDebugRegister (\r
+  IN DEBUG_CPU_CONTEXT                 *CpuContext,\r
+  IN DEBUG_DATA_CLEAR_HW_BREAKPOINT    *ClearHwBreakpoint\r
+  )\r
+{\r
+  if ((ClearHwBreakpoint->IndexMask & BIT0) != 0) {\r
+    CpuContext->Dr0 = 0;\r
+    CpuContext->Dr7 &= ~(0x3 << 0);\r
+  }\r
+  if ((ClearHwBreakpoint->IndexMask & BIT1) != 0) {\r
+    CpuContext->Dr1 = 0;\r
+    CpuContext->Dr7 &= ~(0x3 << 2);\r
+  }\r
+  if ((ClearHwBreakpoint->IndexMask & BIT2) != 0) {\r
+    CpuContext->Dr2 = 0;\r
+    CpuContext->Dr7 &= ~(0x3 << 4);\r
+  }\r
+  if ((ClearHwBreakpoint->IndexMask & BIT3) != 0) {\r
+    CpuContext->Dr3 = 0;\r
+    CpuContext->Dr7 &= ~(0x3 << 6);\r
+  }\r
+}\r
+\r
+/**\r
+  Send acknowledge packet to HOST.\r
+\r
+  @param[in] AckCommand    Type of Acknowledge packet.\r
+\r
+**/\r
+VOID\r
+SendAckPacket (\r
+  IN UINT8                AckCommand\r
+  )\r
+{\r
+  DEBUG_COMMAND_HEADER      DebugCommonHeader;\r
+  DEBUG_PORT_HANDLE         Handle;\r
+\r
+  Handle = GetDebugPortHandle();\r
+\r
+  DebugCommonHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;\r
+  DebugCommonHeader.Command     = AckCommand;\r
+  DebugCommonHeader.DataLength  = 0;\r
+\r
+  DebugPortWriteBuffer (Handle, (UINT8 *) &DebugCommonHeader, sizeof (DEBUG_COMMAND_HEADER));\r
+}\r
+\r
+/**\r
+  Receive acknowledge packet from HOST in specified time.\r
+\r
+  @param[out] Ack           Returned acknowlege type from HOST.\r
+  @param[in]  Timeout       Time out value to wait for acknowlege from HOST.\r
+                            The unit is microsecond.\r
+  @param[out] BreakReceived If BreakReceived is not NULL,\r
+                            TRUE is retured if break-in symbol received.\r
+                            FALSE is retured if break-in symbol not received.\r
+\r
+  @retval  RETRUEN_SUCCESS  Succeed to receive acknowlege packet from HOST,\r
+                            the type of acknowlege packet saved in Ack.\r
+  @retval  RETURN_TIMEOUT   Specified timeout value was up.\r
+\r
+**/\r
+RETURN_STATUS\r
+ReceiveAckPacket (\r
+  OUT UINT8                     *Ack,\r
+  IN  UINTN                     Timeout,\r
+  OUT BOOLEAN                   *BreakReceived OPTIONAL\r
+  )\r
+{\r
+  DEBUG_COMMAND_HEADER      DebugCommonHeader;\r
+  DEBUG_PORT_HANDLE         Handle;\r
+\r
+  Handle = GetDebugPortHandle();\r
+\r
+  while (TRUE) {\r
+    if (DebugPortReadBuffer (Handle, (UINT8 *) &DebugCommonHeader.StartSymbol, 1, Timeout) == 0) {\r
+      return RETURN_TIMEOUT;\r
+    }\r
+    if (DebugCommonHeader.StartSymbol == DEBUG_STARTING_SYMBOL_BREAK) {\r
+      if (BreakReceived != NULL) {\r
+        SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED);\r
+        *BreakReceived = TRUE;\r
+      }\r
+    }\r
+    if (DebugCommonHeader.StartSymbol == DEBUG_STARTING_SYMBOL_NORMAL) {\r
+      break;\r
+    }\r
+  }\r
+  if (DebugPortReadBuffer (Handle, (UINT8 *)&DebugCommonHeader.Command, sizeof (DEBUG_COMMAND_HEADER) - 1, Timeout) == 0) {\r
+    return RETURN_TIMEOUT;\r
+  }\r
+\r
+  *Ack = DebugCommonHeader.Command;\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Receive acknowledge packet OK from HOST in specified time.\r
+\r
+  @param[in]  Timeout       Time out value to wait for acknowlege from HOST.\r
+                            The unit is microsecond.\r
+  @param[out] BreakReceived If BreakReceived is not NULL,\r
+                            TRUE is retured if break-in symbol received.\r
+                            FALSE is retured if break-in symbol not received.\r
+\r
+  @retval  RETRUEN_SUCCESS  Succeed to receive acknowlege packet from HOST,\r
+                            the type of acknowlege packet saved in Ack.\r
+  @retval  RETURN_TIMEOUT   Specified timeout value was up.\r
+\r
+**/\r
+RETURN_STATUS\r
+WaitForAckPacketOK (\r
+  IN  UINTN                     Timeout,\r
+  OUT BOOLEAN                   *BreakReceived OPTIONAL\r
+  )\r
+{\r
+  RETURN_STATUS             Status;\r
+  UINT8                     Ack;\r
+\r
+  while (TRUE) {\r
+    Status = ReceiveAckPacket (&Ack, Timeout, BreakReceived);\r
+    if ((Status == RETURN_SUCCESS && Ack == DEBUG_COMMAND_OK) ||\r
+         Status == RETURN_TIMEOUT) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Receive valid packet from HOST.\r
+\r
+  @param[out] InputPacket    Buffer to receive packet.\r
+  @param[out] BreakReceived  TRUE means break-in symbol received.\r
+                             FALSE means break-in symbol not received.\r
+\r
+  @retval RETURN_SUCCESS   A valid package was reveived in InputPacket.\r
+  @retval RETURN_NOT_READY No valid start symbol received.\r
+  @retval RETURN_TIMEOUT   Timeout occurs.\r
+\r
+**/\r
+RETURN_STATUS\r
+ReceivePacket (\r
+  OUT UINT8             *InputPacket,\r
+  OUT BOOLEAN           *BreakReceived\r
+  )\r
+{\r
+  DEBUG_COMMAND_HEADER  *DebugHeader;\r
+  UINTN                 Received;\r
+  DEBUG_PORT_HANDLE     Handle;\r
+\r
+  Handle = GetDebugPortHandle();\r
+  //\r
+  // Find the valid start symbol\r
+  //\r
+  DebugPortReadBuffer (Handle, InputPacket, 1, 0);\r
+\r
+  if (*InputPacket == DEBUG_STARTING_SYMBOL_BREAK) {\r
+    *BreakReceived = TRUE;\r
+    SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED);\r
+  }\r
+\r
+  if (*InputPacket != DEBUG_STARTING_SYMBOL_NORMAL) {\r
+    return RETURN_NOT_READY;\r
+  }\r
+\r
+  //\r
+  // Read Package header\r
+  //\r
+  Received = DebugPortReadBuffer (Handle, InputPacket + 1, sizeof(DEBUG_COMMAND_HEADER_NO_START_SYMBOL), 0);\r
+  if (Received == 0) {\r
+    return RETURN_TIMEOUT;\r
+  }\r
+\r
+  DebugHeader = (DEBUG_COMMAND_HEADER *) InputPacket;\r
+  //\r
+  // Read the payload if has\r
+  //\r
+  if (DebugHeader->DataLength > 0 && DebugHeader->DataLength < (DEBUG_DATA_MAXIMUM_REAL_DATA - sizeof(DEBUG_COMMAND_HEADER))) {\r
+    InputPacket = InputPacket + 1 + Received;\r
+    Received = DebugPortReadBuffer (Handle, InputPacket, DebugHeader->DataLength, 0);\r
+\r
+    if (Received == 0) {\r
+      return RETURN_TIMEOUT;\r
+    }\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Get current break cause.\r
+\r
+  @param[in] Vector      Vector value of exception or interrupt.\r
+  @param[in] CpuContext  Pointer to save CPU context.\r
+\r
+  @return The type of break cause defined by XXXX\r
+\r
+**/\r
+UINT8\r
+GetBreakCause (\r
+  IN UINTN                    Vector,\r
+  IN DEBUG_CPU_CONTEXT        *CpuContext\r
+  )\r
+{\r
+  UINT8                    Cause;\r
+\r
+  Cause = DEBUG_DATA_BREAK_CAUSE_UNKNOWN;\r
+\r
+  switch (Vector) {\r
+  case DEBUG_INT1_VECTOR:\r
+  case DEBUG_INT3_VECTOR:\r
+\r
+    if (Vector == DEBUG_INT1_VECTOR) {\r
+      //\r
+      // INT 1\r
+      //\r
+      if ((CpuContext->Dr6 & BIT14) != 0) {\r
+        Cause = DEBUG_DATA_BREAK_CAUSE_STEPPING;\r
+\r
+      } else {\r
+        Cause = DEBUG_DATA_BREAK_CAUSE_HW_BREAKPOINT;\r
+      }\r
+    } else {\r
+      //\r
+      // INT 3\r
+      //\r
+      Cause = DEBUG_DATA_BREAK_CAUSE_SW_BREAKPOINT;\r
+    }\r
+\r
+    switch (CpuContext->Dr0) {\r
+    case IMAGE_LOAD_SIGNATURE:\r
+    case IMAGE_UNLOAD_SIGNATURE:\r
+\r
+      if (CpuContext->Dr3 == IO_PORT_BREAKPOINT_ADDRESS) {\r
+\r
+        Cause = (UINT8) ((CpuContext->Dr0 == IMAGE_LOAD_SIGNATURE) ? \r
+          DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD : DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD);\r
+      }\r
+      break;\r
+\r
+    case SOFT_INTERRUPT_SIGNATURE:\r
+   \r
+      if (CpuContext->Dr1 == MEMORY_READY_SIGNATURE) {\r
+        Cause = DEBUG_DATA_BREAK_CAUSE_MEMORY_READY;\r
+        CpuContext->Dr0 = 0;\r
+      } else if (CpuContext->Dr1 == SYSTEM_RESET_SIGNATURE) {\r
+        Cause = DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET;\r
+        CpuContext->Dr0 = 0;\r
+      }\r
+      break;\r
+\r
+    default:\r
+      break;\r
+\r
+    }\r
+\r
+    break;\r
+\r
+  case DEBUG_TIMER_VECTOR:\r
+    Cause = DEBUG_DATA_BREAK_CAUSE_USER_HALT;\r
+    break;\r
+\r
+  default:\r
+    if (Vector < 20) {\r
+      Cause = DEBUG_DATA_BREAK_CAUSE_EXCEPTION;\r
+    }\r
+    break;\r
+  }\r
+\r
+  return Cause;\r
+}\r
+\r
+/**\r
+  Send packet with response data to HOST.\r
+\r
+  @param[in] CpuContext  Pointer to saved CPU context.\r
+  @param[in] Data        Pointer to response data buffer.\r
+  @param[in] DataSize    Size of response data in byte.\r
+\r
+  @retval RETURN_SUCCESS      Response data was sent successfully.\r
+  @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST.\r
+\r
+**/\r
+RETURN_STATUS\r
+SendDataResponsePacket (\r
+  IN DEBUG_CPU_CONTEXT    *CpuContext,\r
+  IN UINT8                *Data,\r
+  IN UINT16               DataSize\r
+  )\r
+{\r
+  UINT8                PacketHeader[DEBUG_DATA_MAXIMUM_LENGTH_FOR_SMALL_COMMANDS];\r
+  BOOLEAN              LastPacket;\r
+  UINT8                Ack;\r
+  UINT8                PacketData[DEBUG_DATA_MAXIMUM_REAL_DATA];\r
+  DEBUG_PORT_HANDLE    Handle;\r
+\r
+  Handle = GetDebugPortHandle();\r
+\r
+  ((DEBUG_COMMAND_HEADER *)PacketHeader)->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;\r
+\r
+  while (TRUE) {\r
+    if (DataSize <= DEBUG_DATA_MAXIMUM_REAL_DATA) {\r
+      LastPacket = TRUE;\r
+      ((DEBUG_COMMAND_HEADER *)PacketHeader)->Command     = DEBUG_COMMAND_OK;\r
+      ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength  = (UINT8) DataSize;\r
+      CopyMem (PacketData, Data, DataSize);\r
+\r
+    } else {\r
+      LastPacket = FALSE;\r
+      ((DEBUG_COMMAND_HEADER *)PacketHeader)->Command     = DEBUG_COMMAND_IN_PROGRESS;\r
+      ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength  = DEBUG_DATA_MAXIMUM_REAL_DATA;\r
+      CopyMem (PacketData, Data, DEBUG_DATA_MAXIMUM_REAL_DATA);\r
+    }\r
+\r
+    DebugPortWriteBuffer (Handle, PacketHeader, sizeof (DEBUG_COMMAND_HEADER));\r
+    DebugPortWriteBuffer (Handle, PacketData, ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength);\r
+\r
+    ReceiveAckPacket(&Ack, 0, NULL);\r
+    switch (Ack) {\r
+    case DEBUG_COMMAND_RESEND:\r
+      //\r
+      // Send the packet again\r
+      //\r
+      break;\r
+\r
+    case DEBUG_COMMAND_CONTINUE:\r
+      //\r
+      // Send the rest packet\r
+      //\r
+      Data     += DEBUG_DATA_MAXIMUM_REAL_DATA;\r
+      DataSize -= DEBUG_DATA_MAXIMUM_REAL_DATA;\r
+      break;\r
+\r
+    case DEBUG_COMMAND_OK:\r
+      if (LastPacket) {\r
+        //\r
+        // If this is the last packet, return RETURN_SUCCESS.\r
+        //\r
+        return RETURN_SUCCESS;\r
+      } else {\r
+        return RETURN_DEVICE_ERROR;\r
+      }\r
+\r
+    default:\r
+      return RETURN_DEVICE_ERROR;\r
+\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Send break cause packet to HOST.\r
+\r
+  @param[in] Vector      Vector value of exception or interrutp.\r
+  @param[in] CpuContext  Pointer to save CPU context.\r
+\r
+  @retval RETURN_SUCCESS      Response data was sent successfully.\r
+  @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST.\r
+\r
+**/\r
+RETURN_STATUS\r
+SendBreakCausePacket (\r
+  IN UINTN                    Vector,\r
+  IN DEBUG_CPU_CONTEXT        *CpuContext\r
+  )\r
+{\r
+  DEBUG_DATA_RESPONSE_BREAK_CAUSE    DebugDataBreakCause;\r
+\r
+  DebugDataBreakCause.StopAddress = CpuContext->Eip;\r
+  DebugDataBreakCause.Cause       = GetBreakCause (Vector, CpuContext);\r
+\r
+  return SendDataResponsePacket (CpuContext, (UINT8 *) &DebugDataBreakCause, (UINT16) sizeof (DEBUG_DATA_RESPONSE_BREAK_CAUSE));\r
+}\r
+\r
+\r
+/**\r
+  The main function to process communication with HOST.\r
+\r
+  It received the command packet from HOST, and sent response data packet to HOST.\r
+\r
+  @param[in]      Vector         Vector value of exception or interrutp.\r
+  @param[in, out] CpuContext     Pointer to saved CPU context.\r
+  @param[in]      BreakReceived  TRUE means break-in symbol received.\r
+                                 FALSE means break-in symbol not received.\r
+\r
+**/\r
+VOID\r
+CommandCommunication (\r
+  IN     UINTN                   Vector,\r
+  IN OUT DEBUG_CPU_CONTEXT       *CpuContext,\r
+  IN     BOOLEAN                 BreakReceived\r
+  )\r
+{\r
+  RETURN_STATUS                 Status;\r
+  UINT8                         InputPacketBuffer[DEBUG_DATA_MAXIMUM_LENGTH_FOR_SMALL_COMMANDS];\r
+  DEBUG_COMMAND_HEADER          *DebugHeader;\r
+  UINT8                         Data8;\r
+  UINT32                        Data32;\r
+  UINT64                        Data64;\r
+  UINTN                         DataN;\r
+  DEBUG_DATA_READ_MEMORY_8      *MemoryRead;\r
+  DEBUG_DATA_WRITE_MEMORY_8     *MemoryWrite;\r
+  DEBUG_DATA_READ_IO            *IoRead;\r
+  DEBUG_DATA_WRITE_IO           *IoWrite;\r
+  DEBUG_DATA_READ_REGISTER      *RegisterRead;\r
+  DEBUG_DATA_WRITE_REGISTER     *RegisterWrite;\r
+  UINT8                         *RegisterBuffer;\r
+  DEBUG_DATA_READ_MSR           *MsrRegisterRead;\r
+  DEBUG_DATA_WRITE_MSR          *MsrRegisterWrite;\r
+  DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM   RegisterGroupSegLim;\r
+  DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE  RegisterGroupSegBase;\r
+  DEBUG_DATA_RESPONSE_GET_REVISION DebugAgentRevision;\r
+  BOOLEAN                       HaltDeferred;\r
+  DEBUG_DATA_RESPONSE_GET_EXCEPTION  Exception;\r
+  UINT32                        ProcessorIndex;\r
+  DEBUG_PORT_HANDLE             Handle;\r
+\r
+  Handle = GetDebugPortHandle();\r
+\r
+  ProcessorIndex  = 0;\r
+  HaltDeferred = BreakReceived;\r
+\r
+  if (MultiProcessorDebugSupport) {\r
+    ProcessorIndex = GetProcessorIndex ();\r
+    SetCpuStopFlagByIndex (ProcessorIndex, TRUE);\r
+  }\r
+\r
+  while (TRUE) {\r
+\r
+    if (MultiProcessorDebugSupport) {\r
+      if (mDebugMpContext.ViewPointIndex != ProcessorIndex) {\r
+        if (mDebugMpContext.RunCommandSet) {\r
+          SetCpuStopFlagByIndex (ProcessorIndex, FALSE);\r
+          CommandGo (CpuContext);\r
+          break;\r
+        } else {\r
+          continue;\r
+        }\r
+      }\r
+    }\r
+\r
+    AcquireDebugPortControl ();\r
+\r
+    Status = ReceivePacket (InputPacketBuffer, &BreakReceived);\r
+\r
+    if (BreakReceived) {\r
+      HaltDeferred = TRUE;\r
+      BreakReceived = FALSE;\r
+    }\r
+\r
+    if (Status != RETURN_SUCCESS) {\r
+      ReleaseDebugPortControl ();\r
+      continue;\r
+    }\r
+\r
+    Data8 = 1;\r
+\r
+    DebugHeader =(DEBUG_COMMAND_HEADER *) InputPacketBuffer;\r
+    switch (DebugHeader->Command) {\r
+\r
+    case DEBUG_COMMAND_RESET:\r
+      SendAckPacket (DEBUG_COMMAND_OK);\r
+      ReleaseDebugPortControl ();\r
+\r
+      ResetCold ();\r
+      //\r
+      // Wait for reset\r
+      //\r
+      CpuDeadLoop ();\r
+      break;\r
+\r
+    case DEBUG_COMMAND_GO:\r
+      CommandGo (CpuContext);\r
+      if (!HaltDeferred) {\r
+        //\r
+        // If no HALT command received when being in-active mode\r
+        //\r
+        if (MultiProcessorDebugSupport) {\r
+          Data32 = FindCpuNotRunning ();\r
+          if (Data32 != -1) {\r
+            //\r
+            // If there are still others processors being in break state,          \r
+            // send OK packet to HOST to finish this go command\r
+            //\r
+            SendAckPacket (DEBUG_COMMAND_OK);\r
+            CpuPause ();\r
+            //\r
+            // Set current view to the next breaking processor\r
+            //\r
+            mDebugMpContext.ViewPointIndex = Data32;\r
+            mDebugMpContext.BreakAtCpuIndex = mDebugMpContext.ViewPointIndex;\r
+            SetCpuBreakFlagByIndex (mDebugMpContext.ViewPointIndex, FALSE);\r
+            //\r
+            // Send break packet to HOST and exit to wait for command packet from HOST.\r
+            //\r
+            SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
+            WaitForAckPacketOK (0, &BreakReceived);\r
+            ReleaseDebugPortControl (); \r
+            break;\r
+          }\r
+\r
+          //\r
+          // If no else processor break, set stop bitmask,\r
+          // and set Running flag for all processors.\r
+          //\r
+          SetCpuStopFlagByIndex (ProcessorIndex, FALSE);\r
+          SetCpuRunningFlag (TRUE);\r
+          CpuPause ();\r
+          //\r
+          // Wait for all processors are in running state \r
+          //\r
+          while (TRUE) {\r
+            if (IsAllCpuRunning ()) {\r
+              break;\r
+            }\r
+          }\r
+          //\r
+          // Set BSP to be current view point.\r
+          //\r
+          SetDebugViewPoint (mDebugMpContext.BspIndex);\r
+          CpuPause ();\r
+          //\r
+          // Clear breaking processor index and running flag\r
+          //\r
+          mDebugMpContext.BreakAtCpuIndex = (UINT32) (-1);\r
+          SetCpuRunningFlag (FALSE);\r
+        }\r
+\r
+        //\r
+        // Send OK packet to HOST to finish this go command\r
+        //\r
+        SendAckPacket (DEBUG_COMMAND_OK);\r
+\r
+        ReleaseDebugPortControl ();\r
+\r
+        return;\r
+\r
+      } else {\r
+        //\r
+        // If reveived HALT command, need to defer the GO command\r
+        //\r
+        SendAckPacket (DEBUG_COMMAND_HALT_PROCESSED);\r
+        HaltDeferred = FALSE;\r
+        Data8 = GetBreakCause (Vector, CpuContext);\r
+        if (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) {\r
+          CpuContext->Dr0 = 0;\r
+          CpuContext->Dr3 = 0;\r
+        }\r
+\r
+        Vector = DEBUG_TIMER_VECTOR;\r
+      }\r
+      break;\r
+\r
+    case DEBUG_COMMAND_BREAK_CAUSE:\r
+\r
+      if (MultiProcessorDebugSupport && ProcessorIndex != mDebugMpContext.BreakAtCpuIndex) {\r
+        Status = SendBreakCausePacket (DEBUG_TIMER_VECTOR, CpuContext);\r
+\r
+      } else {\r
+        Status = SendBreakCausePacket (Vector, CpuContext);\r
+      }\r
+\r
+      break;\r
+\r
+    case DEBUG_COMMAND_SET_HW_BREAKPOINT:\r
+      SetDebugRegister (CpuContext, (DEBUG_DATA_SET_HW_BREAKPOINT *) (DebugHeader + 1));\r
+      SendAckPacket (DEBUG_COMMAND_OK);\r
+      break;\r
+\r
+    case DEBUG_COMMAND_CLEAR_HW_BREAKPOINT:\r
+      ClearDebugRegister (CpuContext, (DEBUG_DATA_CLEAR_HW_BREAKPOINT *) (DebugHeader + 1));\r
+      SendAckPacket (DEBUG_COMMAND_OK);\r
+      break;\r
+\r
+    case DEBUG_COMMAND_SINGLE_STEPPING:\r
+      CommandStepping (CpuContext);\r
+\r
+      mDebugMpContext.BreakAtCpuIndex = (UINT32) (-1);\r
+\r
+      ReleaseDebugPortControl ();\r
+      //\r
+      // Executing stepping command directly without sending ACK packet.\r
+      //\r
+      return;\r
+\r
+    case DEBUG_COMMAND_SET_SW_BREAKPOINT:\r
+      Data64 = (UINTN) (((DEBUG_DATA_SET_SW_BREAKPOINT *) (DebugHeader + 1))->Address);\r
+      Data8 = *(UINT8 *) (UINTN) Data64;\r
+      *(UINT8 *) (UINTN) Data64 = DEBUG_SW_BREAKPOINT_SYMBOL;\r
+      Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data8, (UINT16) sizeof (UINT8));\r
+      break;\r
+\r
+    case DEBUG_COMMAND_READ_MEMORY_64:\r
+      Data8 *= 2;\r
+    case DEBUG_COMMAND_READ_MEMORY_32:\r
+      Data8 *= 2;\r
+    case DEBUG_COMMAND_READ_MEMORY_16:\r
+      Data8 *= 2;\r
+         case DEBUG_COMMAND_READ_MEMORY_8:\r
+      MemoryRead = (DEBUG_DATA_READ_MEMORY_8 *) (DebugHeader + 1);\r
+      Status = SendDataResponsePacket (CpuContext, (UINT8 *) (UINTN) MemoryRead->Address, (UINT16) (MemoryRead->Count * Data8));\r
+      break;\r
+\r
+    case DEBUG_COMMAND_WRITE_MEMORY_64:\r
+      Data8 *= 2;\r
+    case DEBUG_COMMAND_WRITE_MEMORY_32:\r
+      Data8 *= 2;\r
+    case DEBUG_COMMAND_WRITE_MEMORY_16:\r
+      Data8 *= 2;\r
+    case DEBUG_COMMAND_WRITE_MEMORY_8:\r
+      MemoryWrite = (DEBUG_DATA_WRITE_MEMORY_8 *) (DebugHeader + 1);\r
+      CopyMem ((VOID *) (UINTN) MemoryWrite->Address, &MemoryWrite->Data, MemoryWrite->Count * Data8);\r
+      SendAckPacket (DEBUG_COMMAND_OK);\r
+      break;\r
+\r
+    case DEBUG_COMMAND_READ_IO:\r
+      IoRead = (DEBUG_DATA_READ_IO *) (DebugHeader + 1);\r
+      switch (IoRead->Width) {\r
+      case 1:\r
+        Data64  = IoRead8 (IoRead->Port);\r
+        break;\r
+      case 2:\r
+        Data64  = IoRead16 (IoRead->Port);\r
+        break;\r
+      case 4:\r
+        Data64  = IoRead32 (IoRead->Port);\r
+        break;\r
+      case 8:\r
+        Data64  = IoRead64 (IoRead->Port);\r
+        break;\r
+      default:\r
+        Data64  = (UINT64) -1;\r
+      }\r
+      Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, IoRead->Width);\r
+      break;\r
+\r
+    case DEBUG_COMMAND_WRITE_IO:\r
+      IoWrite = (DEBUG_DATA_WRITE_IO *) (DebugHeader + 1);\r
+      switch (IoWrite->Width) {\r
+      case 1:\r
+        Data64  = IoWrite8 (IoWrite->Port, *(UINT8 *) &IoWrite->Data);\r
+        break;\r
+      case 2:\r
+        Data64  = IoWrite16 (IoWrite->Port, *(UINT16 *) &IoWrite->Data);\r
+        break;\r
+      case 4:\r
+        Data64  = IoWrite32 (IoWrite->Port, *(UINT32 *) &IoWrite->Data);\r
+        break;\r
+      case 8:\r
+        Data64  = IoWrite64 (IoWrite->Port, *(UINT64 *) &IoWrite->Data);\r
+        break;\r
+      default:\r
+        Data64  = (UINT64) -1;\r
+      }\r
+      SendAckPacket (DEBUG_COMMAND_OK);\r
+      break;\r
+\r
+    case DEBUG_COMMAND_READ_REGISTER:\r
+      RegisterRead = (DEBUG_DATA_READ_REGISTER *) (DebugHeader + 1);\r
+\r
+      if (RegisterRead->Index < SOFT_DEBUGGER_REGISTER_OTHERS_BASE) {\r
+        Data8 = RegisterRead->Length;\r
+        RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterRead->Index, RegisterRead->Offset, &Data8);\r
+        Status = SendDataResponsePacket (CpuContext, RegisterBuffer, Data8);\r
+        break;\r
+      }\r
+\r
+      if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_TSS_LIM) {\r
+        ReadRegisterGroupSegLim (CpuContext, &RegisterGroupSegLim);\r
+        DataN = * ((UINTN *) &RegisterGroupSegLim + (RegisterRead->Index - SOFT_DEBUGGER_REGISTER_CS_LIM));\r
+        Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
+      } else if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_TSS_BAS) {\r
+        ReadRegisterGroupSegBase (CpuContext, &RegisterGroupSegBase);\r
+        DataN = * ((UINTN *) &RegisterGroupSegBase + (RegisterRead->Index - SOFT_DEBUGGER_REGISTER_CS_BAS));\r
+        Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
+      } else if (RegisterRead->Index < SOFT_DEBUGGER_REGISTER_IDT_LIM) {\r
+        Data64 = ReadRegisterSelectorByIndex (CpuContext, RegisterRead->Index);\r
+        Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, (UINT16) sizeof (UINT64));\r
+      } else {\r
+        switch (RegisterRead->Index) {\r
+        case SOFT_DEBUGGER_REGISTER_IDT_LIM:\r
+          DataN = (UINTN) (CpuContext->Idtr[0] & 0xffff);\r
+          SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
+          break;\r
+        case SOFT_DEBUGGER_REGISTER_GDT_LIM:\r
+          DataN = (UINTN) (CpuContext->Gdtr[0] & 0xffff);\r
+          SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
+          break;\r
+        case SOFT_DEBUGGER_REGISTER_IDT_BAS:\r
+          DataN = (UINTN) RShiftU64 (CpuContext->Idtr[0], 16);\r
+          DataN |= (UINTN) LShiftU64 (CpuContext->Idtr[1], (UINT16) (sizeof (UINTN) * 8 - 16));\r
+          SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
+          break;\r
+        case SOFT_DEBUGGER_REGISTER_GDT_BAS:\r
+          DataN = (UINTN) RShiftU64 (CpuContext->Gdtr[0], 16);\r
+          DataN |= (UINTN) LShiftU64 (CpuContext->Gdtr[1], (UINT16) (sizeof (UINTN) * 8 - 16));\r
+          SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
+          break;\r
+        }\r
+      }\r
+      break;\r
+\r
+    case DEBUG_COMMAND_WRITE_REGISTER:\r
+      RegisterWrite = (DEBUG_DATA_WRITE_REGISTER *) (DebugHeader + 1);\r
+      ArchWriteRegisterBuffer (CpuContext, RegisterWrite->Index, RegisterWrite->Offset, RegisterWrite->Length, (UINT8 *)&RegisterWrite->Value);\r
+      SendAckPacket (DEBUG_COMMAND_OK);\r
+      break;\r
+\r
+    case DEBUG_COMMAND_ARCH_MODE:\r
+      Data8 = DEBUG_ARCH_SYMBOL;\r
+      Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data8, (UINT16) sizeof (UINT8));\r
+      break;\r
+\r
+    case DEBUG_COMMAND_READ_MSR:\r
+      MsrRegisterRead = (DEBUG_DATA_READ_MSR *) (DebugHeader + 1);\r
+      Data64 = AsmReadMsr64 (MsrRegisterRead->Index);\r
+      Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, (UINT16) sizeof (UINT64));\r
+      break;\r
+\r
+    case DEBUG_COMMAND_WRITE_MSR:\r
+      MsrRegisterWrite = (DEBUG_DATA_WRITE_MSR *) (DebugHeader + 1);\r
+      AsmWriteMsr64 (MsrRegisterWrite->Index, MsrRegisterWrite->Value);\r
+      SendAckPacket (DEBUG_COMMAND_OK);\r
+      break;\r
+\r
+    case DEBUG_COMMAND_READ_REGISTER_GROUP:\r
+      Data8 = *(UINT8 *) (DebugHeader + 1);\r
+      Status = ArchReadRegisterGroup (CpuContext, Data8);\r
+      break;\r
+\r
+    case DEBUG_COMMAND_SET_DEBUG_FLAG:\r
+      Data32 = *(UINT32 *) (DebugHeader + 1);\r
+      SetDebugFlag (Data32);\r
+      SendAckPacket (DEBUG_COMMAND_OK);\r
+      break;\r
+\r
+    case DEBUG_COMMAND_GET_REVISION:\r
+      DebugAgentRevision.Revision = DEBUG_AGENT_REVISION;\r
+      DebugAgentRevision.Capabilities = DEBUG_AGENT_CAPABILITIES;\r
+      Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DebugAgentRevision, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_REVISION));\r
+      break;\r
+\r
+    case DEBUG_COMMAND_GET_EXCEPTION:\r
+      Exception.ExceptionNum  = (UINT8) Vector;\r
+      Exception.ExceptionData = 0;\r
+      Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Exception, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_EXCEPTION));\r
+      break;\r
+\r
+    case DEBUG_COMMAND_SET_VIEWPOINT:\r
+      Data32 = *(UINT32 *) (DebugHeader + 1);\r
+\r
+      if (MultiProcessorDebugSupport) {\r
+        if (IsCpuStopped (Data32)) {\r
+          SetDebugViewPoint (Data32);\r
+          SendAckPacket (DEBUG_COMMAND_OK);\r
+        } else {\r
+          //\r
+          // If CPU is not halted\r
+          //\r
+          SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);\r
+        }\r
+      } else if (Data32 == 0) {\r
+        SendAckPacket (DEBUG_COMMAND_OK);\r
+\r
+      } else {\r
+        SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);\r
+      }\r
+\r
+      break;\r
+\r
+    case DEBUG_COMMAND_GET_VIEWPOINT:\r
+      Data32 = mDebugMpContext.ViewPointIndex;\r
+      SendDataResponsePacket(CpuContext, (UINT8 *) &Data32, (UINT16) sizeof (UINT32));\r
+      break;\r
+\r
+    default:\r
+      SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);\r
+      break;\r
+    }\r
+\r
+    if (Status == RETURN_UNSUPPORTED) {\r
+      SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);\r
+    } else if (Status != RETURN_SUCCESS) {\r
+      SendAckPacket (DEBUG_COMMAND_ABORT);\r
+    }\r
+\r
+    ReleaseDebugPortControl ();\r
+    CpuPause ();\r
+  }\r
+}\r
+\r
+/**\r
+  C function called in interrupt handler.\r
+\r
+  @param[in] Vector      Vector value of exception or interrutp.\r
+  @param[in] CpuContext  Pointer to save CPU context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InterruptProcess (\r
+  IN UINT32                          Vector,\r
+  IN DEBUG_CPU_CONTEXT               *CpuContext\r
+  )\r
+{\r
+  UINT8                     InputCharacter;\r
+  UINT8                     BreakCause;\r
+  UINTN                     SavedEip;\r
+  BOOLEAN                   BreakReceived;\r
+  UINT32                    ProcessorIndex;\r
+  UINT32                    CurrentDebugTimerInitCount;\r
+  DEBUG_PORT_HANDLE         Handle;\r
+  UINT8                     Data8;\r
+\r
+  Handle = GetDebugPortHandle();\r
+\r
+  ProcessorIndex = 0;\r
+  BreakReceived  = FALSE;\r
+\r
+  if (MultiProcessorDebugSupport) {\r
+    ProcessorIndex = GetProcessorIndex ();\r
+    while (mDebugMpContext.RunCommandSet);\r
+  }\r
+\r
+  switch (Vector) {\r
+  case DEBUG_INT1_VECTOR:\r
+  case DEBUG_INT3_VECTOR:\r
+\r
+    BreakCause = GetBreakCause (Vector, CpuContext);\r
+\r
+    if (BreakCause == DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET) {\r
+\r
+      //\r
+      // Init break, if no ack received after 200ms, return\r
+      //\r
+      SendAckPacket (DEBUG_COMMAND_INIT_BREAK);\r
+      if (WaitForAckPacketOK (200 * 1000, &BreakReceived) != RETURN_SUCCESS) {\r
+        break;\r
+      }\r
+\r
+      SetHostConnectedFlag ();\r
+      CommandCommunication (Vector, CpuContext, BreakReceived);\r
+\r
+    } else if (BreakCause == DEBUG_DATA_BREAK_CAUSE_STEPPING) {\r
+\r
+      //\r
+      // Stepping is finished, send Ack package.\r
+      //\r
+      if (MultiProcessorDebugSupport) {\r
+        mDebugMpContext.BreakAtCpuIndex = ProcessorIndex;\r
+      }\r
+      SendAckPacket (DEBUG_COMMAND_OK);\r
+      CommandCommunication (Vector, CpuContext, BreakReceived);\r
+\r
+    } else if (BreakCause == DEBUG_DATA_BREAK_CAUSE_MEMORY_READY) {\r
+\r
+      //\r
+      // Memory is ready\r
+      //\r
+      SendAckPacket (DEBUG_COMMAND_MEMORY_READY);\r
+      WaitForAckPacketOK (0, &BreakReceived);\r
+      CommandCommunication (Vector, CpuContext, BreakReceived);\r
+\r
+    } else {\r
+\r
+      if (BreakCause == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || BreakCause == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) {\r
+        \r
+        //\r
+        // Set AL to DEBUG_AGENT_IMAGE_CONTINUE\r
+        //\r
+        Data8 = DEBUG_AGENT_IMAGE_CONTINUE;\r
+        ArchWriteRegisterBuffer (CpuContext, SOFT_DEBUGGER_REGISTER_AX, 0, 1, &Data8);\r
+\r
+        if (!IsHostConnected ()) {\r
+          //\r
+          // If HOST is not connected, return\r
+          //\r
+          break;\r
+        }\r
+      }\r
+\r
+      AcquireDebugPortControl ();\r
+\r
+      if (MultiProcessorDebugSupport) {\r
+        if(!IsAllCpuRunning ()) {\r
+          //\r
+          // If other processors have been stopped\r
+          //\r
+          SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);\r
+        } else {\r
+          //\r
+          // If no any processor was stopped, try to halt other processors\r
+          //\r
+          HaltOtherProcessors (ProcessorIndex);\r
+          SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
+          WaitForAckPacketOK (0, &BreakReceived);\r
+        }\r
+      } else {\r
+        SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
+        WaitForAckPacketOK (0, &BreakReceived);\r
+      }\r
+\r
+      ReleaseDebugPortControl ();\r
+\r
+      if (Vector == DEBUG_INT3_VECTOR) {\r
+        //\r
+        // go back address located "0xCC"\r
+        //\r
+        CpuContext->Eip--;\r
+        SavedEip = CpuContext->Eip;\r
+        CommandCommunication (Vector, CpuContext, BreakReceived);\r
+        if ((SavedEip == CpuContext->Eip) &&\r
+            (*(UINT8 *) (UINTN) CpuContext->Eip == DEBUG_SW_BREAKPOINT_SYMBOL)) {\r
+          //\r
+          // If this is not a software breakpoint set by HOST,\r
+          // restore EIP\r
+          //\r
+          CpuContext->Eip++;\r
+        }\r
+      } else {\r
+        CommandCommunication (Vector, CpuContext, BreakReceived);\r
+      }\r
+    }\r
+\r
+    break;\r
+\r
+  case DEBUG_TIMER_VECTOR:\r
+\r
+    if (MultiProcessorDebugSupport) {\r
+      if (IsBsp (ProcessorIndex)) {\r
+        //\r
+        // If current processor is BSP, check Apic timer's init count if changed,\r
+        // it may be re-written when switching BSP.\r
+        // If it changed, re-initialize debug timer\r
+        //\r
+        CurrentDebugTimerInitCount = GetApicTimerInitCount ();\r
+        if (mDebugMpContext.DebugTimerInitCount != CurrentDebugTimerInitCount) {\r
+          InitializeDebugTimer ();\r
+        }\r
+      }\r
+\r
+      if (!IsBsp (ProcessorIndex) || mDebugMpContext.IpiSentByAp) {\r
+        //\r
+        // If current processor is not BSP or this is one IPI sent by AP\r
+        //\r
+        if (mDebugMpContext.BreakAtCpuIndex != (UINT32) (-1)) {\r
+          CommandCommunication (Vector, CpuContext, FALSE);\r
+        }\r
+\r
+        //\r
+        // Clear EOI before exiting interrupt process routine.\r
+        //\r
+        SendApicEoi ();\r
+        break;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Only BSP could run here\r
+    //\r
+\r
+    AcquireDebugPortControl ();\r
+    \r
+    while (DebugPortPollBuffer (Handle)) {\r
+      //\r
+      // If there is data in debug port, will check whether it is break-in symbol,\r
+      // If yes, go into communication mode with HOST.\r
+      // If no, exit interrupt process.\r
+      //\r
+      DebugPortReadBuffer (Handle, &InputCharacter, 1, 0);\r
+      if (InputCharacter == DEBUG_STARTING_SYMBOL_BREAK) {\r
+        SendAckPacket (DEBUG_COMMAND_OK);\r
+        if (MultiProcessorDebugSupport) {\r
+          if(FindCpuNotRunning () != -1) {\r
+            SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);\r
+          } else {\r
+            HaltOtherProcessors (ProcessorIndex);\r
+          }\r
+        }\r
+        ReleaseDebugPortControl ();\r
+        CommandCommunication (Vector, CpuContext, BreakReceived);\r
+        AcquireDebugPortControl ();\r
+        break;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Clear EOI before exiting interrupt process routine.\r
+    //\r
+    SendApicEoi ();\r
+\r
+    ReleaseDebugPortControl ();\r
+\r
+    break;\r
+\r
+  default:\r
+\r
+    if (Vector <= DEBUG_EXCEPT_SIMD) {\r
+\r
+      AcquireDebugPortControl ();\r
+\r
+      if (MultiProcessorDebugSupport) {\r
+        if(FindCpuNotRunning () != -1) {\r
+          SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);\r
+        } else {\r
+          HaltOtherProcessors (ProcessorIndex);\r
+        }\r
+      }\r
+      SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
+      WaitForAckPacketOK (0, &BreakReceived);\r
+      ReleaseDebugPortControl ();\r
+      CommandCommunication (Vector, CpuContext, BreakReceived);\r
+    }\r
+    break;\r
+  }\r
+\r
+  if (MultiProcessorDebugSupport) {\r
+    //\r
+    // Clear flag and wait for all processors run here\r
+    //\r
+    SetIpiSentByApFlag (FALSE);\r
+    while (mDebugMpContext.RunCommandSet);\r
+  }\r
+\r
+  return;\r
+}\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h
new file mode 100644 (file)
index 0000000..9671ca4
--- /dev/null
@@ -0,0 +1,308 @@
+/** @file\r
+  Command header of for Debug Agent library instance.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _DEBUG_AGENT_H_\r
+#define _DEBUG_AGENT_H_\r
+\r
+#include <Register/LocalApic.h>\r
+\r
+#include <Guid/DebugAgentGuid.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/ResetSystemLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/DebugCommunicationLib.h>\r
+#include <Library/DebugAgentLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/SynchronizationLib.h>\r
+#include <Library/LocalApicLib.h>\r
+\r
+#include <TransferProtocol.h>\r
+#include <ImageDebugSupport.h>\r
+\r
+#include "DebugMp.h"\r
+#include "DebugTimer.h"\r
+#include "ArchDebugSupport.h"\r
+\r
+#define DEBUG_AGENT_REVISION            ((0 << 16) | 01)\r
+#define DEBUG_AGENT_CAPABILITIES        0\r
+\r
+#define DEBUG_INT1_VECTOR               1\r
+#define DEBUG_INT3_VECTOR               3\r
+#define DEBUG_TIMER_VECTOR              32\r
+#define DEBUG_MAILBOX_VECTOR            33\r
+\r
+#define SOFT_INTERRUPT_SIGNATURE    SIGNATURE_32('S','O','F','T')\r
+#define SYSTEM_RESET_SIGNATURE      SIGNATURE_32('S','Y','S','R')\r
+#define MEMORY_READY_SIGNATURE      SIGNATURE_32('M','E','M','R')\r
+\r
+extern UINTN  Exception0Handle;\r
+extern UINTN  TimerInterruptHandle;\r
+extern UINT16 ExceptionStubHeaderSize;\r
+\r
+typedef union {\r
+  struct {\r
+    UINT32  HostPresent      : 1;\r
+    UINT32  BreakOnNextSmi   : 1;\r
+    UINT32  Reserved         : 30;\r
+  } Bits;\r
+  UINT32  Uint32;\r
+} DEBUG_AGENT_FLAG;\r
+\r
+#pragma pack(1)\r
+typedef struct {\r
+  DEBUG_AGENT_FLAG           DebugFlag;\r
+  UINT64                     DebugPortHandle;\r
+} DEBUG_AGENT_MAILBOX;\r
+#pragma pack()\r
+\r
+typedef union {\r
+  struct {\r
+    UINT32  LimitLow    : 16;\r
+    UINT32  BaseLow     : 16;\r
+    UINT32  BaseMid     : 8;\r
+    UINT32  Type        : 4;\r
+    UINT32  System      : 1;\r
+    UINT32  Dpl         : 2;\r
+    UINT32  Present     : 1;\r
+    UINT32  LimitHigh   : 4;\r
+    UINT32  Software    : 1;\r
+    UINT32  Reserved    : 1;\r
+    UINT32  DefaultSize : 1;\r
+    UINT32  Granularity : 1;\r
+    UINT32  BaseHigh    : 8;\r
+  } Bits;\r
+  UINT64  Uint64;\r
+} IA32_GDT;\r
+\r
+/**\r
+  Caller provided function to be invoked at the end of DebugPortInitialize().\r
+\r
+  Refer to the descrption for DebugPortInitialize() for more details.\r
+\r
+  @param[in] Context           The first input argument of DebugPortInitialize().\r
+  @param[in] DebugPortHandle   Debug port handle created by Debug Communication Libary.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeDebugAgentPhase2 (\r
+  IN VOID                  *Context,\r
+  IN DEBUG_PORT_HANDLE     DebugPortHandle\r
+  );\r
+\r
+/**\r
+  Initialize IDT entries to support source level debug.\r
+\r
+**/\r
+VOID\r
+InitializeDebugIdt (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Write specified register into save CPU context.\r
+\r
+  @param[in] CpuContext         Pointer to saved CPU context.\r
+  @param[in] Index              Register index value.\r
+  @param[in] Offset             Offset in register address range\r
+  @param[in] Width              Data width to read.\r
+  @param[in] RegisterBuffer     Pointer to input buffer with data.\r
+\r
+**/\r
+VOID\r
+ArchWriteRegisterBuffer (\r
+  IN DEBUG_CPU_CONTEXT               *CpuContext,\r
+  IN UINT8                           Index,\r
+  IN UINT8                           Offset,\r
+  IN UINT8                           Width,\r
+  IN UINT8                           *RegisterBuffer\r
+  );\r
+\r
+/**\r
+  Read register value from saved CPU context.\r
+\r
+  @param[in] CpuContext         Pointer to saved CPU context.\r
+  @param[in] Index              Register index value.\r
+  @param[in] Offset             Offset in register address range\r
+  @param[in] Width              Data width to read.\r
+\r
+  @return The address of register value.\r
+\r
+**/\r
+UINT8 *\r
+ArchReadRegisterBuffer (\r
+  IN DEBUG_CPU_CONTEXT               *CpuContext,\r
+  IN UINT8                           Index,\r
+  IN UINT8                           Offset,\r
+  IN UINT8                           *Width\r
+  );\r
+\r
+/**\r
+  Send packet with response data to HOST.\r
+\r
+  @param[in] CpuContext  Pointer to saved CPU context.\r
+  @param[in] Data        Pointer to response data buffer.\r
+  @param[in] DataSize    Size of response data in byte.\r
+\r
+  @retval RETURN_SUCCESS      Response data was sent successfully.\r
+  @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST.\r
+\r
+**/\r
+RETURN_STATUS\r
+SendDataResponsePacket (\r
+  IN DEBUG_CPU_CONTEXT    *CpuContext,\r
+  IN UINT8                *Data,\r
+  IN UINT16               DataSize\r
+  );\r
+\r
+/**\r
+  Read segment selector by register index.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterIndex        Register Index.\r
+\r
+  @return Value of segment selector.\r
+\r
+**/\r
+UINT64\r
+ReadRegisterSelectorByIndex (\r
+  IN DEBUG_CPU_CONTEXT                       *CpuContext,\r
+  IN UINT8                                   RegisterIndex\r
+  );\r
+\r
+/**\r
+  Read group register of common registers.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterGroup        Pointer to Group registers.\r
+\r
+**/\r
+VOID\r
+ReadRegisterGroup (\r
+  IN DEBUG_CPU_CONTEXT                       *CpuContext,\r
+  IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP  *RegisterGroup\r
+  );\r
+\r
+/**\r
+  Read group register of Segment Base.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterGroupSegBase Pointer to Group registers.\r
+\r
+**/\r
+VOID\r
+ReadRegisterGroupSegBase (\r
+  IN DEBUG_CPU_CONTEXT                              *CpuContext,\r
+  IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE *RegisterGroupSegBase\r
+  );\r
+\r
+/**\r
+  Read gourp register of Segment Limit.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterGroupSegLim  Pointer to Group registers.\r
+\r
+**/\r
+VOID\r
+ReadRegisterGroupSegLim (\r
+  IN DEBUG_CPU_CONTEXT                             *CpuContext,\r
+  IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM *RegisterGroupSegLim\r
+  );\r
+\r
+/**\r
+  Read group register by group index.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] GroupIndex           Group Index.\r
+\r
+  @retval RETURN_SUCCESS         Read successfully.\r
+  @retval RETURN_NOT_SUPPORTED   Group index cannot be supported.\r
+\r
+**/\r
+RETURN_STATUS\r
+ArchReadRegisterGroup (\r
+  IN DEBUG_CPU_CONTEXT                             *CpuContext,\r
+  IN UINT8                                         GroupIndex\r
+  );\r
+\r
+/**\r
+  Send acknowledge packet to HOST.\r
+\r
+  @param AckCommand    Type of Acknowledge packet.\r
+\r
+**/\r
+VOID\r
+SendAckPacket (\r
+  IN UINT8                AckCommand\r
+  );\r
+\r
+/**\r
+  Receive acknowledge packet OK from HOST in specified time.\r
+\r
+  @param[in]  Timeout       Time out value to wait for acknowlege from HOST.\r
+                            The unit is microsecond.\r
+  @param[out] BreakReceived If BreakReceived is not NULL,\r
+                            TRUE is retured if break-in symbol received.\r
+                            FALSE is retured if break-in symbol not received.\r
+\r
+  @retval  RETRUEN_SUCCESS  Succeed to receive acknowlege packet from HOST,\r
+                            the type of acknowlege packet saved in Ack.\r
+  @retval  RETURN_TIMEOUT   Specified timeout value was up.\r
+\r
+**/\r
+RETURN_STATUS\r
+WaitForAckPacketOK (\r
+  IN  UINTN                     Timeout,\r
+  OUT BOOLEAN                   *BreakReceived OPTIONAL\r
+  );\r
+\r
+/**\r
+  Check if HOST is connected based on Mailbox.\r
+\r
+  @retval TRUE        HOST is connected.\r
+  @retval FALSE       HOST is not connected.\r
+\r
+**/\r
+BOOLEAN\r
+IsHostConnected (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get Debug Agent Mailbox pointer.\r
+\r
+  @return Mailbox pointer.\r
+\r
+**/\r
+DEBUG_AGENT_MAILBOX *\r
+GetMailboxPointer (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get debug port handle.\r
+\r
+  @return Debug port handle.\r
+\r
+**/\r
+DEBUG_PORT_HANDLE\r
+GetDebugPortHandle (\r
+  VOID\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugMp.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugMp.c
new file mode 100644 (file)
index 0000000..7d053fa
--- /dev/null
@@ -0,0 +1,365 @@
+/** @file\r
+  Multi-Processor support functions implementation.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "DebugAgent.h"\r
+\r
+DEBUG_MP_CONTEXT volatile  mDebugMpContext = {0,0,0,0,0,0,0,0,FALSE,FALSE};\r
+\r
+DEBUG_CPU_DATA volatile  mDebugCpuData = {0};\r
+\r
+/**\r
+  Acquire access control on debug port.\r
+\r
+  It will block in the function if cannot get the access control.\r
+\r
+**/\r
+VOID\r
+AcquireDebugPortControl (\r
+  VOID\r
+  )\r
+{\r
+  if (!MultiProcessorDebugSupport) {\r
+    return;\r
+  }\r
+\r
+  while (TRUE) {\r
+    if (AcquireSpinLockOrFail (&mDebugMpContext.DebugPortSpinLock)) {\r
+      break;\r
+    }\r
+    CpuPause ();\r
+    continue;\r
+  }\r
+}\r
+\r
+/**\r
+  Release access control on debug port.\r
+\r
+**/\r
+VOID\r
+ReleaseDebugPortControl (\r
+  VOID\r
+  )\r
+{\r
+  if (!MultiProcessorDebugSupport) {\r
+    return;\r
+  }\r
+\r
+  ReleaseSpinLock (&mDebugMpContext.DebugPortSpinLock);\r
+}\r
+\r
+/**\r
+  Acquire access control on MP context.\r
+\r
+  It will block in the function if cannot get the access control.\r
+\r
+**/\r
+VOID\r
+AcquireMpContextControl (\r
+  VOID\r
+  )\r
+{\r
+  while (TRUE) {\r
+    if (AcquireSpinLockOrFail (&mDebugMpContext.MpContextSpinLock)) {\r
+      break;\r
+    }\r
+    CpuPause ();\r
+    continue;\r
+  }\r
+}\r
+\r
+/**\r
+  Release access control on MP context.\r
+\r
+**/\r
+VOID\r
+ReleaseMpContextControl (\r
+  VOID\r
+  )\r
+{\r
+  ReleaseSpinLock (&mDebugMpContext.MpContextSpinLock);\r
+}\r
+\r
+/**\r
+  Break the other processor by send IPI.\r
+\r
+  @param[in] CurrentProcessorIndex  Current processor index value.\r
+\r
+**/\r
+VOID\r
+HaltOtherProcessors (\r
+  IN UINT32             CurrentProcessorIndex\r
+  )\r
+{\r
+\r
+  if (!IsBsp (CurrentProcessorIndex)) {\r
+    SetIpiSentByApFlag (TRUE);;\r
+  }\r
+\r
+  mDebugMpContext.BreakAtCpuIndex = CurrentProcessorIndex;\r
+\r
+  //\r
+  // Send fixed IPI to other processors.\r
+  //\r
+  SendFixedIpiAllExcludingSelf (DEBUG_TIMER_VECTOR);\r
+  \r
+}\r
+\r
+/**\r
+  Get the current processor's index.\r
+\r
+  @return Processor index value.\r
+\r
+**/\r
+UINT32\r
+GetProcessorIndex (\r
+  VOID\r
+  )\r
+{\r
+  UINT32                Index;\r
+  UINT16                LocalApicID;\r
+\r
+  LocalApicID = (UINT16) GetApicId ();\r
+\r
+  AcquireMpContextControl ();\r
+\r
+  for (Index = 0; Index < mDebugCpuData.CpuCount; Index ++) {\r
+    if (mDebugCpuData.ApicID[Index] == LocalApicID) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Index == mDebugCpuData.CpuCount) {\r
+    mDebugCpuData.ApicID[Index] = LocalApicID;\r
+    mDebugCpuData.CpuCount ++ ;\r
+  }\r
+\r
+  ReleaseMpContextControl ();\r
+\r
+  return Index;\r
+}\r
+\r
+/**\r
+  Check if the specified processor is BSP or not.\r
+\r
+  @param[in] ProcessorIndex Processor index value.\r
+\r
+  @retval TRUE    It is BSP.\r
+  @retval FALSE   It isn't BSP.\r
+\r
+**/\r
+BOOLEAN\r
+IsBsp (\r
+  IN UINT32             ProcessorIndex\r
+  )\r
+{\r
+  if (AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE_ADDRESS, 8, 8) == 1) {\r
+    if (mDebugMpContext.BspIndex != ProcessorIndex) {\r
+      AcquireMpContextControl ();\r
+      mDebugMpContext.BspIndex = ProcessorIndex;\r
+      ReleaseMpContextControl ();\r
+    }\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Set processor stop flag bitmask in MP context.\r
+\r
+  @param[in] ProcessorIndex Processor index value.\r
+  @param[in] StopFlag       TRUE means set stop flag.\r
+                            FALSE means clean break flag.\r
+\r
+**/\r
+VOID\r
+SetCpuStopFlagByIndex (\r
+  IN UINT32             ProcessorIndex,\r
+  IN BOOLEAN            StopFlag\r
+  )\r
+{\r
+  UINT8                 Value;\r
+  UINTN                 Index;\r
+\r
+  AcquireMpContextControl ();\r
+\r
+  Value = mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8];\r
+  Index = ProcessorIndex % 8;\r
+  if (StopFlag) {\r
+    Value = BitFieldWrite8 (Value, Index, Index, 1);\r
+  } else {\r
+    Value = BitFieldWrite8 (Value, Index, Index, 0);\r
+  }\r
+  mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8] = Value;\r
+\r
+  ReleaseMpContextControl ();\r
+}\r
+\r
+/**\r
+  Set processor break flag bitmask in MP context.\r
+\r
+  @param[in] ProcessorIndex Processor index value.\r
+  @param[in] BreakFlag      TRUE means set break flag.\r
+                            FALSE means clean break flag.\r
+\r
+**/\r
+VOID\r
+SetCpuBreakFlagByIndex (\r
+  IN UINT32             ProcessorIndex,\r
+  IN BOOLEAN            BreakFlag\r
+  )\r
+{\r
+  UINT8                 Value;\r
+  UINTN                 Index;\r
+\r
+  AcquireMpContextControl ();\r
+\r
+  Value = mDebugMpContext.CpuBreakMask[ProcessorIndex / 8];\r
+  Index = ProcessorIndex % 8;\r
+  if (BreakFlag) {\r
+    Value = BitFieldWrite8 (Value, Index, Index, 1);\r
+  } else {\r
+    Value = BitFieldWrite8 (Value, Index, Index, 0);\r
+  }\r
+  mDebugMpContext.CpuBreakMask[ProcessorIndex / 8] = Value;\r
+\r
+  ReleaseMpContextControl ();\r
+}\r
+\r
+/**\r
+  Check if processor is stopped already.\r
+\r
+  @param[in] ProcessorIndex   Processor index value.\r
+\r
+  @retval TRUE        Processor is stopped already.\r
+  @retval TRUE        Processor isn't stopped.\r
+\r
+**/\r
+BOOLEAN\r
+IsCpuStopped (\r
+  IN UINT32              ProcessorIndex\r
+  )\r
+{\r
+  UINT8                 CpuMask;\r
+\r
+  CpuMask = (UINT8) (1 << (ProcessorIndex % 8));\r
+\r
+  if ((mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8] & CpuMask) != 0) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Set the run command flag.\r
+\r
+  @param[in] RunningFlag   TRUE means run command flag is set.\r
+                           FALSE means run command flag is cleared.\r
+\r
+**/\r
+VOID\r
+SetCpuRunningFlag (\r
+  IN BOOLEAN            RunningFlag\r
+  )\r
+{\r
+  AcquireMpContextControl ();\r
+\r
+  mDebugMpContext.RunCommandSet = RunningFlag;\r
+\r
+  ReleaseMpContextControl ();\r
+}\r
+\r
+/**\r
+  Set the current view point to be debugged.\r
+\r
+  @param[in] ProcessorIndex   Processor index value.\r
+\r
+**/\r
+VOID\r
+SetDebugViewPoint (\r
+  IN UINT32             ProcessorIndex\r
+  )\r
+{\r
+  AcquireMpContextControl ();\r
+\r
+  mDebugMpContext.ViewPointIndex = ProcessorIndex;\r
+\r
+  ReleaseMpContextControl ();\r
+}\r
+\r
+/**\r
+  Initialize debug timer.\r
+\r
+  @param[in] IpiSentByApFlag   TRUE means this IPI is sent by AP.\r
+                               FALSE means this IPI is sent by BSP.\r
+\r
+**/\r
+VOID\r
+SetIpiSentByApFlag (\r
+  IN BOOLEAN            IpiSentByApFlag\r
+  )\r
+{\r
+  AcquireMpContextControl ();\r
+\r
+  mDebugMpContext.IpiSentByAp = IpiSentByApFlag;\r
+\r
+  ReleaseMpContextControl ();\r
+}\r
+\r
+/**\r
+  Check if any processor breaks.\r
+\r
+  @retval others      There is at least one processor broken, the minimum\r
+                      index number of Processor returned.\r
+  @retval -1          No any processor broken.\r
+\r
+**/\r
+UINT32\r
+FindCpuNotRunning (\r
+  VOID\r
+  )\r
+{\r
+  UINT32               Index;\r
+  \r
+  for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index ++) {\r
+    if (mDebugMpContext.CpuBreakMask[Index] != 0) {\r
+      return  (UINT32) LowBitSet32 (mDebugMpContext.CpuBreakMask[Index]) + Index * 8;\r
+    }\r
+  }\r
+  return (UINT32)-1;\r
+}\r
+  \r
+/**\r
+  Check if all processors are in running status.\r
+\r
+  @retval TRUE        All processors run.\r
+  @retval FALSE       At least one processor does not run.\r
+\r
+**/\r
+BOOLEAN\r
+IsAllCpuRunning (\r
+  VOID\r
+  )\r
+{\r
+  UINTN              Index;\r
+  \r
+  for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index ++) {\r
+    if (mDebugMpContext.CpuStopStatusMask[Index] != 0) {\r
+      return FALSE;\r
+    }\r
+  }\r
+  return TRUE;\r
+}\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugMp.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugMp.h
new file mode 100644 (file)
index 0000000..db12459
--- /dev/null
@@ -0,0 +1,221 @@
+/** @file\r
+  Header file for Multi-Processor support.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _DEBUG_MP_H_\r
+#define _DEBUG_MP_H_\r
+\r
+#define DEBUG_CPU_MAX_COUNT             256\r
+\r
+typedef struct {\r
+  UINT32    CpuCount;                            ///< Processor count\r
+  UINT16    ApicID[DEBUG_CPU_MAX_COUNT];         ///< Record the local apic id for each processor\r
+} DEBUG_CPU_DATA;\r
+\r
+typedef struct {\r
+  SPIN_LOCK                 MpContextSpinLock;   ///< Lock for writting MP context\r
+  SPIN_LOCK                 DebugPortSpinLock;   ///< Lock for access debug port\r
+  UINT8                     CpuBreakMask[DEBUG_CPU_MAX_COUNT/8];        ///< Bitmask of all breaking CPUs\r
+  UINT8                     CpuStopStatusMask[DEBUG_CPU_MAX_COUNT/8];   ///< Bitmask of CPU stop status\r
+  UINT32                    ViewPointIndex;      ///< Current view point to be debugged\r
+  UINT32                    BspIndex;            ///< Processor index value of BSP\r
+  UINT32                    BreakAtCpuIndex;     ///< Processor index value of the current breaking CPU\r
+  UINT32                    DebugTimerInitCount; ///< Record BSP's init timer count\r
+  BOOLEAN                   IpiSentByAp;         ///< TRUR: IPI is sent by AP. TALSE: IPI is sent by BSP\r
+  BOOLEAN                   RunCommandSet;       ///< TRUE: RUN commmand is not executed. FALSE : RUN command is executed.\r
+} DEBUG_MP_CONTEXT;\r
+\r
+extern CONST BOOLEAN               MultiProcessorDebugSupport;\r
+extern DEBUG_MP_CONTEXT volatile   mDebugMpContext;\r
+extern DEBUG_CPU_DATA   volatile   mDebugCpuData;\r
+\r
+/**\r
+  Break the other processor by send IPI.\r
+\r
+  @param[in] CurrentProcessorIndex  Current processor index value.\r
+\r
+**/\r
+VOID\r
+HaltOtherProcessors (\r
+  IN UINT32             CurrentProcessorIndex\r
+  );\r
+\r
+/**\r
+  Get the current processor's index.\r
+\r
+  @return Processor index value.\r
+\r
+**/\r
+UINT32\r
+GetProcessorIndex (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Acquire access control on MP context.\r
+\r
+  It will block in the function if cannot get the access control.\r
+\r
+**/\r
+VOID\r
+AcquireMpContextControl (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Release access control on MP context.\r
+\r
+**/\r
+VOID\r
+ReleaseMpContextControl (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Acquire access control on debug port.\r
+\r
+  It will block in the function if cannot get the access control.\r
+\r
+**/\r
+VOID\r
+AcquireDebugPortControl (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Release access control on debug port.\r
+\r
+**/\r
+VOID\r
+ReleaseDebugPortControl (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Check if the specified processor is BSP or not.\r
+\r
+  @param[in] ProcessorIndex Processor index value.\r
+\r
+  @retval TRUE    It is BSP.\r
+  @retval FALSE   It isn't BSP.\r
+\r
+**/\r
+BOOLEAN\r
+IsBsp (\r
+  IN UINT32             ProcessorIndex\r
+  );\r
+\r
+/**\r
+  Set processor stop flag bitmask in MP context.\r
+\r
+  @param[in] ProcessorIndex Processor index value.\r
+  @param[in] StopFlag       TRUE means set stop flag.\r
+                            FALSE means clean break flag.\r
+\r
+**/\r
+VOID\r
+SetCpuStopFlagByIndex (\r
+  IN UINT32             ProcessorIndex,\r
+  IN BOOLEAN            StopFlag\r
+  );\r
+\r
+/**\r
+  Set processor break flag bitmask in MP context.\r
+\r
+  @param[in] ProcessorIndex Processor index value.\r
+  @param[in] BreakFlag      TRUE means set break flag.\r
+                            FALSE means clean break flag.\r
+\r
+**/\r
+VOID\r
+SetCpuBreakFlagByIndex (\r
+  IN UINT32             ProcessorIndex,\r
+  IN BOOLEAN            BreakFlag\r
+  );\r
+\r
+/**\r
+  Check if processor is stopped already.\r
+\r
+  @param[in] ProcessorIndex   Processor index value.\r
+\r
+  @retval TRUE        Processor is stopped already.\r
+  @retval FALSE       Processor isn't stopped.\r
+\r
+**/\r
+BOOLEAN\r
+IsCpuStopped (\r
+  IN UINT32              ProcessorIndex\r
+  );\r
+\r
+/**\r
+  Set the run command flag.\r
+\r
+  @param[in] RunningFlag   TRUE means run command flag is set.\r
+                           FALSE means run command flag is cleared.\r
+\r
+**/\r
+VOID\r
+SetCpuRunningFlag (\r
+  IN BOOLEAN            RunningFlag\r
+  );\r
+\r
+/**\r
+  Set the current view point to be debugged.\r
+\r
+  @param[in] ProcessorIndex   Processor index value.\r
+\r
+**/\r
+VOID\r
+SetDebugViewPoint (\r
+  IN UINT32             ProcessorIndex\r
+  );\r
+\r
+/**\r
+  Initialize debug timer.\r
+\r
+  @param[in] IpiSentByApFlag   TRUE means this IPI is sent by AP.\r
+                               FALSE means this IPI is sent by BSP.\r
+\r
+**/\r
+VOID\r
+SetIpiSentByApFlag (\r
+  IN BOOLEAN            IpiSentByApFlag\r
+  );\r
+\r
+/**\r
+  Check if any processor breaks.\r
+\r
+  @retval others      There is at least one processor broken, the minimum\r
+                      index number of Processor returned.\r
+  @retval -1          No any processor broken.\r
+\r
+**/\r
+UINT32\r
+FindCpuNotRunning (\r
+  VOID\r
+  );\r
+  \r
+/**\r
+  Check if all processors are in running status.\r
+\r
+  @retval TRUE        All processors run.\r
+  @retval FALSE       At least one processor does not run.\r
+\r
+**/\r
+BOOLEAN\r
+IsAllCpuRunning (\r
+  VOID\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.c
new file mode 100644 (file)
index 0000000..d473df8
--- /dev/null
@@ -0,0 +1,83 @@
+/** @file\r
+  Code for debug timer to support debug agent library implementation.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "DebugAgent.h"\r
+\r
+/**\r
+  Initialize CPU local APIC timer.\r
+\r
+**/\r
+VOID\r
+InitializeDebugTimer (\r
+  VOID\r
+  )\r
+{\r
+  UINTN       ApicTimerDivisor;\r
+  UINT32      InitialCount;\r
+\r
+  GetApicTimerState (&ApicTimerDivisor, NULL, NULL);\r
+\r
+  //\r
+  // Cpu Local Apic timer interrupt frequency, it is set to 0.1s\r
+  //\r
+  InitialCount = (UINT32)DivU64x32 (\r
+                   MultU64x64 (\r
+                     PcdGet32(PcdFSBClock) / (UINT32)ApicTimerDivisor,\r
+                     100\r
+                     ),\r
+                   1000\r
+                   );\r
+\r
+  InitializeApicTimer (ApicTimerDivisor, InitialCount, TRUE, DEBUG_TIMER_VECTOR);\r
+\r
+  if (MultiProcessorDebugSupport) {\r
+    mDebugMpContext.DebugTimerInitCount = InitialCount;\r
+  }\r
+}\r
+\r
+/**\r
+  Enable/Disable the interrupt of debug timer and return the interrupt state\r
+  prior to the operation.\r
+\r
+  If EnableStatus is TRUE, enable the interrupt of debug timer.\r
+  If EnableStatus is FALSE, disable the interrupt of debug timer.\r
+\r
+  @param[in] EnableStatus    Enable/Disable.\r
+\r
+  @retval TRUE  Debug timer interrupt were enabled on entry to this call.\r
+  @retval FALSE Debug timer interrupt were disabled on entry to this call.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+SaveAndSetDebugTimerInterrupt (\r
+  IN BOOLEAN                EnableStatus\r
+  )\r
+{\r
+  BOOLEAN     OldInterruptState;\r
+  BOOLEAN     OldDebugTimerInterruptState;\r
+\r
+  OldInterruptState = SaveAndDisableInterrupts ();\r
+  OldDebugTimerInterruptState = GetApicTimerInterruptState ();\r
+  \r
+  if (EnableStatus) {\r
+    EnableApicTimerInterrupt ();\r
+  } else {\r
+    DisableApicTimerInterrupt ();\r
+  }\r
+\r
+  SetInterruptState (OldInterruptState);\r
+  return OldDebugTimerInterruptState;\r
+}\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.h
new file mode 100644 (file)
index 0000000..4970f93
--- /dev/null
@@ -0,0 +1,28 @@
+/** @file\r
+  Header file for debug timer to support debug agent library implementation.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _DEBUG_TIMER_H_\r
+#define _DEBUG_TIMER_H_\r
+\r
+/**\r
+  Initialize debug timer.\r
+\r
+**/\r
+VOID\r
+InitializeDebugTimer (\r
+  VOID\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c
new file mode 100644 (file)
index 0000000..ab724ff
--- /dev/null
@@ -0,0 +1,242 @@
+/** @file\r
+  Public include file for Debug Port Library.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "DebugAgent.h"\r
+\r
+/**\r
+  Read the offset of FP / MMX / XMM registers by register index.\r
+\r
+  @param[in]  Index    Register index.\r
+  @param[out] Width    Register width returned.\r
+\r
+  @return Offset in register address range.\r
+\r
+**/\r
+UINT16\r
+ArchReadFxStatOffset (\r
+  IN  UINT8                     Index,\r
+  OUT UINT8                     *Width\r
+  )\r
+{\r
+  if (Index < SOFT_DEBUGGER_REGISTER_ST0) {\r
+    switch (Index) {\r
+    case SOFT_DEBUGGER_REGISTER_FP_FCW:\r
+      *Width = (UINT8) sizeof (UINT16);\r
+      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Fcw);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_FSW:\r
+         *Width = (UINT8) sizeof (UINT16);\r
+      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Fsw);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_FTW:\r
+      *Width = (UINT8) sizeof (UINT16);\r
+      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Ftw);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_OPCODE:\r
+      *Width = (UINT8) sizeof (UINT16);\r
+      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Opcode);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_EIP:\r
+      *Width = (UINT8) sizeof (UINTN);\r
+      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Eip);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_CS:\r
+      *Width = (UINT8) sizeof (UINT16);\r
+      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Cs);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:\r
+      *Width = (UINT8) sizeof (UINTN);\r
+      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, DataOffset);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_DS:\r
+      *Width = (UINT8) sizeof (UINT16);\r
+      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Ds);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_MXCSR:\r
+      *Width = (UINT8) sizeof (UINTN);\r
+      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Mxcsr);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:\r
+      *Width = (UINT8) sizeof (UINTN);\r
+      return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Mxcsr_Mask);\r
+    }\r
+  }\r
+\r
+  if (Index < SOFT_DEBUGGER_REGISTER_XMM0) {\r
+    *Width = 10;\r
+  } else if (Index < SOFT_DEBUGGER_REGISTER_MM0 ) {\r
+    *Width = 16;\r
+  } else {\r
+    *Width = 8;\r
+    Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;\r
+  }\r
+\r
+  return (UINT16)(OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16);\r
+}\r
+\r
+/**\r
+  Write specified register into save CPU context.\r
+\r
+  @param[in] CpuContext         Pointer to saved CPU context.\r
+  @param[in] Index              Register index value.\r
+  @param[in] Offset             Offset in register address range.\r
+  @param[in] Width              Data width to read.\r
+  @param[in] RegisterBuffer     Pointer to input buffer with data.\r
+\r
+**/\r
+VOID\r
+ArchWriteRegisterBuffer (\r
+  IN DEBUG_CPU_CONTEXT               *CpuContext,\r
+  IN UINT8                           Index,\r
+  IN UINT8                           Offset,\r
+  IN UINT8                           Width,\r
+  IN UINT8                           *RegisterBuffer\r
+  )\r
+{\r
+  UINT8           *Buffer;\r
+  if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {\r
+    Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_IA32_FX_SAVE_STATE) + Index * 4;\r
+  } else {\r
+    //\r
+    // If it is MMX register, adjust its index position\r
+    //\r
+    if (Index >= SOFT_DEBUGGER_REGISTER_MM0) {\r
+      Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;\r
+    }\r
+    //\r
+    // FPU/MMX/XMM registers\r
+    //\r
+    Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, &Width);\r
+  }\r
+\r
+  CopyMem (Buffer + Offset, RegisterBuffer, Width);\r
+}\r
+\r
+/**\r
+  Read register value from saved CPU context.\r
+\r
+  @param[in] CpuContext         Pointer to saved CPU context.\r
+  @param[in] Index              Register index value.\r
+  @param[in] Offset             Offset in register address range\r
+  @param[in] Width              Data width to read.\r
+\r
+  @return The address of register value.\r
+\r
+**/\r
+UINT8 *\r
+ArchReadRegisterBuffer (\r
+  IN DEBUG_CPU_CONTEXT               *CpuContext,\r
+  IN UINT8                           Index,\r
+  IN UINT8                           Offset,\r
+  IN UINT8                           *Width\r
+  )\r
+{\r
+  UINT8           *Buffer;\r
+\r
+  if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {\r
+    Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_IA32_FX_SAVE_STATE) + Index * 4;\r
+    if (*Width == 0) {\r
+      *Width = (UINT8) sizeof (UINTN);\r
+    }\r
+  } else {\r
+    //\r
+    // FPU/MMX/XMM registers\r
+    //\r
+    Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, Width);\r
+  }\r
+\r
+  return Buffer;\r
+}\r
+\r
+/**\r
+  Read group register of common registers.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterGroup        Pointer to Group registers.\r
+\r
+**/\r
+VOID\r
+ReadRegisterGroup (\r
+  IN DEBUG_CPU_CONTEXT                       *CpuContext,\r
+  IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP  *RegisterGroup\r
+  )\r
+{\r
+  RegisterGroup->Cs     = (UINT16) CpuContext->Cs;\r
+  RegisterGroup->Ds     = (UINT16) CpuContext->Ds;\r
+  RegisterGroup->Es     = (UINT16) CpuContext->Es;\r
+  RegisterGroup->Fs     = (UINT16) CpuContext->Fs;\r
+  RegisterGroup->Gs     = (UINT16) CpuContext->Gs;\r
+  RegisterGroup->Ss     = (UINT16) CpuContext->Ss;\r
+  RegisterGroup->Eflags = CpuContext->Eflags;\r
+  RegisterGroup->Ebp    = CpuContext->Ebp;\r
+  RegisterGroup->Eip    = CpuContext->Eip;\r
+  RegisterGroup->Esp    = CpuContext->Esp;\r
+  RegisterGroup->Eax    = CpuContext->Eax;\r
+  RegisterGroup->Ebx    = CpuContext->Ebx;\r
+  RegisterGroup->Ecx    = CpuContext->Ecx;\r
+  RegisterGroup->Edx    = CpuContext->Edx;\r
+  RegisterGroup->Esi    = CpuContext->Esi;\r
+  RegisterGroup->Edi    = CpuContext->Edi;\r
+  RegisterGroup->Dr0    = CpuContext->Dr0;\r
+  RegisterGroup->Dr1    = CpuContext->Dr1;\r
+  RegisterGroup->Dr2    = CpuContext->Dr2;\r
+  RegisterGroup->Dr3    = CpuContext->Dr3;\r
+  RegisterGroup->Dr6    = CpuContext->Dr6;\r
+  RegisterGroup->Dr7    = CpuContext->Dr7;\r
+}\r
+\r
+/**\r
+  Initialize IDT entries to support source level debug.\r
+\r
+**/\r
+VOID\r
+InitializeDebugIdt (\r
+  VOID\r
+  )\r
+{\r
+  IA32_IDT_GATE_DESCRIPTOR   *IdtEntry;\r
+  UINTN                      InterruptHandler;\r
+  IA32_DESCRIPTOR            IdtDescriptor;\r
+  UINTN                      Index;\r
+  UINT16                     CodeSegment;\r
+\r
+  AsmReadIdtr (&IdtDescriptor);\r
+\r
+  //\r
+  // Use current CS as the segment selector of interrupt gate in IDT\r
+  //\r
+  CodeSegment = AsmReadCs ();\r
+\r
+  IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
+\r
+  for (Index = 0; Index < 20; Index ++) {\r
+    if ((PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {\r
+      //\r
+      // If the exception is masked to be reserved, skip it\r
+      //\r
+      continue;\r
+    }\r
+    InterruptHandler = (UINTN)&Exception0Handle + Index * ExceptionStubHeaderSize;\r
+    IdtEntry[Index].Bits.OffsetLow  = (UINT16)(UINTN)InterruptHandler;\r
+    IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);\r
+    IdtEntry[Index].Bits.Selector        = CodeSegment;\r
+    IdtEntry[Index].Bits.GateType        = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
+  }\r
+\r
+  InterruptHandler = (UINTN) &TimerInterruptHandle;\r
+  IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetLow  = (UINT16)(UINTN)InterruptHandler;\r
+  IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);\r
+  IdtEntry[Index].Bits.Selector        = CodeSegment;\r
+  IdtEntry[Index].Bits.GateType        = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
+}\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.h
new file mode 100644 (file)
index 0000000..7df3cb9
--- /dev/null
@@ -0,0 +1,31 @@
+/** @file\r
+  IA32 specific defintions for debug agent library instance.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _ARCH_DEBUG_SUPPORT_H_\r
+#define _ARCH_DEBUG_SUPPORT_H_\r
+\r
+#include "ArchRegisters.h"\r
+#include "TransferProtocol.h"\r
+\r
+typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_IA32          DEBUG_DATA_REPONSE_READ_REGISTER_GROUP;\r
+typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM_IA32   DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM;\r
+typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE_IA32  DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE;\r
+\r
+#define DEBUG_SW_BREAKPOINT_SYMBOL       0xcc\r
+\r
+#define DEBUG_ARCH_SYMBOL                DEBUG_DATA_BREAK_CPU_ARCH_IA32\r
+\r
+typedef DEBUG_DATA_IA32_SYSTEM_CONTEXT   DEBUG_CPU_CONTEXT;\r
+\r
+#endif\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchReadGroupRegister.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchReadGroupRegister.c
new file mode 100644 (file)
index 0000000..59ebd00
--- /dev/null
@@ -0,0 +1,210 @@
+/** @file\r
+  IA32 Group registers read support functions.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "DebugAgent.h"\r
+\r
+/**\r
+  Read group register of Segment Base.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterGroupSegBase Pointer to Group registers.\r
+\r
+**/\r
+VOID\r
+ReadRegisterGroupSegBase (\r
+  IN DEBUG_CPU_CONTEXT                              *CpuContext,\r
+  IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE *RegisterGroupSegBase\r
+  )\r
+{\r
+  IA32_DESCRIPTOR               *Ia32Descriptor;\r
+  IA32_GDT                      *Ia32Gdt;\r
+  UINTN                         Index;\r
+\r
+  Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;\r
+  Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);\r
+\r
+  Index = CpuContext->Cs / 8;\r
+  RegisterGroupSegBase->CsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+  Index = CpuContext->Ss / 8;\r
+  RegisterGroupSegBase->SsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+  Index = CpuContext->Gs / 8;\r
+  RegisterGroupSegBase->GsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+  Index = CpuContext->Fs / 8;\r
+  RegisterGroupSegBase->FsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+  Index = CpuContext->Es / 8;\r
+  RegisterGroupSegBase->EsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+  Index = CpuContext->Ds / 8;\r
+  RegisterGroupSegBase->DsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+\r
+  RegisterGroupSegBase->LdtBas = 0;\r
+  RegisterGroupSegBase->TssBas = 0;\r
+}\r
+\r
+/**\r
+  Read gourp register of Segment Limit.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterGroupSegLim  Pointer to Group registers.\r
+\r
+**/\r
+VOID\r
+ReadRegisterGroupSegLim (\r
+  IN DEBUG_CPU_CONTEXT                             *CpuContext,\r
+  IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM *RegisterGroupSegLim\r
+  )\r
+{\r
+  IA32_DESCRIPTOR               *Ia32Descriptor;\r
+  IA32_GDT                      *Ia32Gdt;\r
+  UINTN                         Index;\r
+\r
+  Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;\r
+  Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);\r
+\r
+  Index = CpuContext->Cs / 8;\r
+  RegisterGroupSegLim->CsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->CsLim = (RegisterGroupSegLim->CsLim << 12) | 0xfff;\r
+  }\r
+\r
+  Index = CpuContext->Ss / 8;\r
+  RegisterGroupSegLim->SsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->SsLim = (RegisterGroupSegLim->SsLim << 12) | 0xfff;\r
+  }\r
+\r
+  Index = CpuContext->Gs / 8;\r
+  RegisterGroupSegLim->GsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->GsLim = (RegisterGroupSegLim->GsLim << 12) | 0xfff;\r
+  }\r
+\r
+  Index = CpuContext->Fs / 8;\r
+  RegisterGroupSegLim->FsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->FsLim = (RegisterGroupSegLim->FsLim << 12) | 0xfff;\r
+  }\r
+\r
+  Index = CpuContext->Es / 8;\r
+  RegisterGroupSegLim->EsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->EsLim = (RegisterGroupSegLim->EsLim << 12) | 0xfff;\r
+  }\r
+\r
+  Index = CpuContext->Ds / 8;\r
+  RegisterGroupSegLim->DsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->DsLim = (RegisterGroupSegLim->DsLim << 12) | 0xfff;\r
+  }\r
+\r
+  RegisterGroupSegLim->LdtLim = 0xffff;\r
+  RegisterGroupSegLim->TssLim = 0xffff;\r
+}\r
+\r
+/**\r
+  Read group register by group index.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] GroupIndex           Group Index.\r
+\r
+  @retval RETURN_SUCCESS         Read successfully.\r
+  @retval RETURN_NOT_SUPPORTED   Group index cannot be supported.\r
+\r
+**/\r
+RETURN_STATUS\r
+ArchReadRegisterGroup (\r
+  IN DEBUG_CPU_CONTEXT                             *CpuContext,\r
+  IN UINT8                                         GroupIndex\r
+  )\r
+{\r
+  DEBUG_DATA_REPONSE_READ_REGISTER_GROUP  RegisterGroup;\r
+  DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM   RegisterGroupSegLim;\r
+  DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE  RegisterGroupSegBase;\r
+\r
+  switch (GroupIndex) {\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_GPDRS32:\r
+    ReadRegisterGroup (CpuContext, &RegisterGroup);\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP));\r
+    break;\r
+\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_LIMITS32:\r
+    ReadRegisterGroupSegLim (CpuContext, &RegisterGroupSegLim);\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroupSegLim, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM));\r
+    break;\r
+\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_BASES32:\r
+    ReadRegisterGroupSegBase (CpuContext, &RegisterGroupSegBase);\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroupSegBase, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE));\r
+    break;\r
+\r
+  default:\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Read segment selector by register index.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterIndex        Register Index.\r
+\r
+  @return Value of segment selector.\r
+\r
+**/\r
+UINT64\r
+ReadRegisterSelectorByIndex (\r
+  IN DEBUG_CPU_CONTEXT                       *CpuContext,\r
+  IN UINT8                                   RegisterIndex\r
+  )\r
+{\r
+  IA32_DESCRIPTOR               *Ia32Descriptor;\r
+  IA32_GDT                      *Ia32Gdt;\r
+  UINT16                        Selector;\r
+  UINT32                        Data32;\r
+\r
+  Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;\r
+  Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);\r
+\r
+  Selector = 0;\r
+\r
+  switch (RegisterIndex) {\r
+  case SOFT_DEBUGGER_REGISTER_CSAS:\r
+    Selector = (UINT16) CpuContext->Cs;\r
+    break;\r
+  case SOFT_DEBUGGER_REGISTER_SSAS:\r
+    Selector = (UINT16) CpuContext->Ss;\r
+    break;\r
+  case SOFT_DEBUGGER_REGISTER_GSAS:\r
+    Selector = (UINT16) CpuContext->Gs;\r
+    break;\r
+  case SOFT_DEBUGGER_REGISTER_FSAS:\r
+    Selector = (UINT16) CpuContext->Fs;\r
+    break;\r
+  case SOFT_DEBUGGER_REGISTER_ESAS:\r
+    Selector = (UINT16) CpuContext->Es;\r
+    break;\r
+  case SOFT_DEBUGGER_REGISTER_DSAS:\r
+    Selector = (UINT16) CpuContext->Ds;\r
+  case SOFT_DEBUGGER_REGISTER_LDTAS:\r
+  case SOFT_DEBUGGER_REGISTER_TSSAS:\r
+    return 0x00820000;\r
+    break;\r
+  }\r
+\r
+  Data32 = (UINT32) RShiftU64 (Ia32Gdt[Selector / 8].Uint64, 24);\r
+  return (Data32 & (UINT32)(~0xff)) | Selector;\r
+\r
+}\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchRegisters.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchRegisters.h
new file mode 100644 (file)
index 0000000..3c27958
--- /dev/null
@@ -0,0 +1,156 @@
+/** @file\r
+  IA32 register defintions needed by debug transfer protocol.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _ARCH_REGISTERS_H_\r
+#define _ARCH_REGISTERS_H_\r
+\r
+///\r
+/// FXSAVE_STATE\r
+/// FP / MMX / XMM registers (see fxrstor instruction definition)\r
+///\r
+typedef struct {\r
+  UINT16  Fcw;\r
+  UINT16  Fsw;\r
+  UINT16  Ftw;\r
+  UINT16  Opcode;\r
+  UINT32  Eip;\r
+  UINT16  Cs;\r
+  UINT16  Reserved1;\r
+  UINT32  DataOffset;\r
+  UINT16  Ds;\r
+  UINT8   Reserved2[2];\r
+  UINT32  Mxcsr;\r
+  UINT32  Mxcsr_Mask;\r
+  UINT8   St0Mm0[10];\r
+  UINT8   Reserved3[6];\r
+  UINT8   St1Mm1[10];\r
+  UINT8   Reserved4[6];\r
+  UINT8   St2Mm2[10];\r
+  UINT8   Reserved5[6];\r
+  UINT8   St3Mm3[10];\r
+  UINT8   Reserved6[6];\r
+  UINT8   St4Mm4[10];\r
+  UINT8   Reserved7[6];\r
+  UINT8   St5Mm5[10];\r
+  UINT8   Reserved8[6];\r
+  UINT8   St6Mm6[10];\r
+  UINT8   Reserved9[6];\r
+  UINT8   St7Mm7[10];\r
+  UINT8   Reserved10[6];\r
+  UINT8   Xmm0[16];\r
+  UINT8   Xmm1[16];\r
+  UINT8   Xmm2[16];\r
+  UINT8   Xmm3[16];\r
+  UINT8   Xmm4[16];\r
+  UINT8   Xmm5[16];\r
+  UINT8   Xmm6[16];\r
+  UINT8   Xmm7[16];\r
+  UINT8   Reserved11[14 * 16];\r
+} DEBUG_DATA_IA32_FX_SAVE_STATE;\r
+\r
+///\r
+///  IA-32 processor context definition\r
+///\r
+typedef struct {\r
+  DEBUG_DATA_IA32_FX_SAVE_STATE  FxSaveState;\r
+  UINT32                         Dr0;\r
+  UINT32                         Dr1;\r
+  UINT32                         Dr2;\r
+  UINT32                         Dr3;\r
+  UINT32                         Dr6;\r
+  UINT32                         Dr7;\r
+  UINT32                         Eflags;\r
+  UINT32                         Ldtr;\r
+  UINT32                         Tr;\r
+  UINT32                         Gdtr[2];\r
+  UINT32                         Idtr[2];\r
+  UINT32                         Eip;\r
+  UINT32                         Gs;\r
+  UINT32                         Fs;\r
+  UINT32                         Es;\r
+  UINT32                         Ds;\r
+  UINT32                         Cs;\r
+  UINT32                         Ss;\r
+  UINT32                         Cr0;\r
+  UINT32                         Cr1;  ///< Reserved\r
+  UINT32                         Cr2;\r
+  UINT32                         Cr3;\r
+  UINT32                         Cr4;\r
+  UINT32                         Edi;\r
+  UINT32                         Esi;\r
+  UINT32                         Ebp;\r
+  UINT32                         Esp;\r
+  UINT32                         Edx;\r
+  UINT32                         Ecx;\r
+  UINT32                         Ebx;\r
+  UINT32                         Eax;\r
+} DEBUG_DATA_IA32_SYSTEM_CONTEXT;\r
+\r
+///\r
+///  IA32 GROUP register\r
+///\r
+typedef struct {\r
+  UINT16         Cs;\r
+  UINT16         Ds;\r
+  UINT16         Es;\r
+  UINT16         Fs;\r
+  UINT16         Gs;\r
+  UINT16         Ss;\r
+  UINT32         Eflags;\r
+  UINT32         Ebp;\r
+  UINT32         Eip;\r
+  UINT32         Esp;\r
+  UINT32         Eax;\r
+  UINT32         Ebx;\r
+  UINT32         Ecx;\r
+  UINT32         Edx;\r
+  UINT32         Esi;\r
+  UINT32         Edi;\r
+  UINT32         Dr0;\r
+  UINT32         Dr1;\r
+  UINT32         Dr2;\r
+  UINT32         Dr3;\r
+  UINT32         Dr6;\r
+  UINT32         Dr7;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_IA32;\r
+\r
+///\r
+///  IA32 Segment Limit GROUP register\r
+///\r
+typedef struct {\r
+  UINT32         CsLim;\r
+  UINT32         SsLim;\r
+  UINT32         GsLim;\r
+  UINT32         FsLim;\r
+  UINT32         EsLim;\r
+  UINT32         DsLim;\r
+  UINT32         LdtLim;\r
+  UINT32         TssLim;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM_IA32;\r
+\r
+///\r
+///  IA32 Segment Base GROUP register\r
+///\r
+typedef struct {\r
+  UINT32         CsBas;\r
+  UINT32         SsBas;\r
+  UINT32         GsBas;\r
+  UINT32         FsBas;\r
+  UINT32         EsBas;\r
+  UINT32         DsBas;\r
+  UINT32         LdtBas;\r
+  UINT32         TssBas;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE_IA32;\r
+\r
+#endif\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
new file mode 100644 (file)
index 0000000..365947f
--- /dev/null
@@ -0,0 +1,360 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# Module Name:\r
+#\r
+#   AsmFuncs.S\r
+#\r
+# Abstract:\r
+#\r
+#   Debug interrupt handle functions.\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+#include "DebugException.h"\r
+\r
+ASM_GLOBAL ASM_PFX(InterruptProcess)\r
+ASM_GLOBAL ASM_PFX(Exception0Handle)\r
+ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)\r
+ASM_GLOBAL ASM_PFX(TimerInterruptHandle)\r
+ASM_GLOBAL ASM_PFX(CommonEntry)\r
+\r
+.data\r
+\r
+ASM_PFX(ExceptionStubHeaderSize):  .word     ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)\r
+\r
+.text\r
+\r
+ASM_PFX(Exception0Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $0, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception1Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $1, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception2Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $2, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception3Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $3, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception4Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $4, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception5Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $5, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception6Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $6, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception7Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $7, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception8Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $8, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception9Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $9, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception10Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $10, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception11Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $11, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception12Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $12, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception13Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $13, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception14Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $14, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception15Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $15, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception16Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $16, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception17Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $17, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception18Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $18, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception19Handle):\r
+   cli\r
+   pushl %eax\r
+   mov   $19, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+\r
+ASM_PFX(TimerInterruptHandle):\r
+   cli\r
+   pushl %eax\r
+   mov   $32, %eax\r
+   jmp   ASM_PFX(CommonEntry)\r
+\r
+\r
+ASM_PFX(CommonEntry):\r
+\r
+#---------------------------------------;\r
+# _CommonEntry                  ;\r
+#----------------------------------------------------------------------------;\r
+# The follow algorithm is used for the common interrupt routine.\r
+# Entry from each interrupt with a push eax and eax=interrupt number\r
+#\r
+# +---------------------+\r
+# +    EFlags           +\r
+# +---------------------+\r
+# +    CS               +\r
+# +---------------------+\r
+# +    EIP              +\r
+# +---------------------+\r
+# +    Error Code       +\r
+# +---------------------+\r
+# + EAX / Vector Number +\r
+# +---------------------+\r
+# +    EBP              +\r
+# +---------------------+ <-- EBP\r
+#\r
+\r
+# We need to determine if any extra data was pushed by the exception\r
+  cmpl    $DEBUG_EXCEPT_DOUBLE_FAULT, %eax\r
+  je      NoExtrPush\r
+  cmpl    $DEBUG_EXCEPT_INVALID_TSS, %eax\r
+  je      NoExtrPush\r
+  cmpl    $DEBUG_EXCEPT_SEG_NOT_PRESENT, %eax\r
+  je      NoExtrPush\r
+  cmpl    $DEBUG_EXCEPT_STACK_FAULT, %eax\r
+  je      NoExtrPush\r
+  cmpl    $DEBUG_EXCEPT_GP_FAULT, %eax\r
+  je      NoExtrPush\r
+  cmpl    $DEBUG_EXCEPT_PAGE_FAULT, %eax\r
+  je      NoExtrPush\r
+  cmpl    $DEBUG_EXCEPT_ALIGNMENT_CHECK, %eax\r
+  je      NoExtrPush\r
+\r
+  pushl    (%esp)\r
+  movl     $0, 4(%esp)\r
+\r
+NoExtrPush:\r
+\r
+  pushl   %ebp\r
+  movl    %esp,%ebp\r
+\r
+  #\r
+  # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
+  # is 16-byte aligned\r
+  #\r
+  andl    $0xfffffff0,%esp\r
+  subl    $12,%esp\r
+\r
+## UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
+  pushl   0x4(%ebp)\r
+  pushl   %ebx\r
+  pushl   %ecx\r
+  pushl   %edx\r
+  mov     %eax, %ebx                   # save vector in ebx\r
+  leal    24(%ebp),%ecx\r
+  pushl   %ecx                         # save original ESP\r
+  pushl   (%ebp)\r
+  pushl   %esi\r
+  pushl   %edi\r
+\r
+## UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+  movl    %cr4, %eax\r
+  orl     $0x208,%eax\r
+  movl    %eax, %cr4\r
+  pushl   %eax\r
+  movl    %cr3, %eax\r
+  pushl   %eax\r
+  movl    %cr2, %eax\r
+  pushl   %eax\r
+  xorl    %eax,%eax\r
+  pushl   %eax\r
+  movl    %cr0, %eax\r
+  pushl   %eax\r
+\r
+## UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
+  movl    %ss,%eax\r
+  pushl   %eax\r
+  movzwl  16(%ebp), %eax\r
+  pushl   %eax\r
+  movl    %ds,%eax\r
+  pushl   %eax\r
+  movl    %es,%eax\r
+  pushl   %eax\r
+  movl    %fs,%eax\r
+  pushl   %eax\r
+  movl    %gs,%eax\r
+  pushl   %eax\r
+\r
+## UINT32  Eip;\r
+  pushl   12(%ebp)\r
+\r
+## UINT32  Gdtr[2], Idtr[2];\r
+  subl    $8,%esp\r
+  sidt    (%esp)\r
+  subl    $8,%esp\r
+  sgdt    (%esp)\r
+\r
+## UINT32  Ldtr, Tr;\r
+  xorl    %eax,%eax\r
+  strl    %eax\r
+  pushl   %eax\r
+  sldtl   %eax\r
+  pushl   %eax\r
+\r
+## UINT32  EFlags;\r
+  pushl   20(%ebp)\r
+\r
+## UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+  movl    %dr7, %eax\r
+  pushl   %eax\r
+## clear Dr7 while executing debugger itself\r
+  xorl    %eax,%eax\r
+#  movl    %eax, %dr7\r
+\r
+  movl    %dr6, %eax\r
+  pushl   %eax\r
+## insure all status bits in dr6 are clear...\r
+  xorl    %eax,%eax\r
+  movl    %eax, %dr6\r
+\r
+  movl    %dr3, %eax\r
+  pushl   %eax\r
+  movl    %dr2, %eax\r
+  pushl   %eax\r
+  movl    %dr1, %eax\r
+  pushl   %eax\r
+  movl    %dr0, %eax\r
+  pushl   %eax\r
+\r
+## FX_SAVE_STATE_IA32 FxSaveState;\r
+  subl    $512,%esp\r
+  movl    %esp,%edi\r
+  .byte 0x0f, 0xae, 0x07   # fxsave [edi]\r
+\r
+## Clear Direction Flag\r
+  cld\r
+       \r
+## Prepare parameter and call C function\r
+  pushl   %esp\r
+  pushl   %ebx\r
+  call    ASM_PFX(InterruptProcess)\r
+  addl    $8,%esp\r
+\r
+## FX_SAVE_STATE_IA32 FxSaveState;\r
+  movl    %esp,%esi\r
+  .byte 0x0f, 0xae, 0x0e   # fxrstor [esi]\r
+  addl    $512,%esp\r
+\r
+## UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+  popl    %eax\r
+  movl    %eax, %dr0\r
+  popl    %eax\r
+  movl    %eax, %dr1\r
+  popl    %eax\r
+  movl    %eax, %dr2\r
+  popl    %eax\r
+  movl    %eax, %dr3\r
+## skip restore of dr6.  We cleared dr6 during the context save.\r
+  addl    $4,%esp\r
+  popl    %eax\r
+  movl    %eax, %dr7\r
+\r
+## UINT32  EFlags;\r
+  popl    20(%ebp)\r
+\r
+## UINT32  Ldtr, Tr;\r
+## UINT32  Gdtr[2], Idtr[2];\r
+## Best not let anyone mess with these particular registers...\r
+  addl     $24,%esp\r
+\r
+## UINT32  Eip;\r
+   pop     12(%ebp)\r
+\r
+## UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
+## NOTE - modified segment registers could hang the debugger...  We\r
+##        could attempt to insulate ourselves against this possibility,\r
+##        but that poses risks as well.\r
+##\r
+  popl    %gs\r
+  popl    %fs\r
+  popl    %es\r
+  popl    %ds\r
+  popl    16(%ebp)\r
+  popl    %ss\r
+\r
+## UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+  popl    %eax\r
+  movl    %eax, %cr0\r
+  addl    $4,%esp   # not for Cr1\r
+  popl    %eax\r
+  movl    %eax, %cr2\r
+  popl    %eax\r
+  movl    %eax, %cr3\r
+  popl    %eax\r
+  movl    %eax, %cr4\r
+\r
+## UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
+  popl    %edi\r
+  popl    %esi\r
+  addl    $4,%esp  # not for ebp\r
+  addl    $4,%esp  # not for esp\r
+  popl    %edx\r
+  popl    %ecx\r
+  popl    %ebx\r
+  popl    %eax\r
+\r
+  movl    %ebp,%esp\r
+  popl    %ebp\r
+  addl    $8,%esp   # skip eax\r
+  iretl\r
+  \r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm
new file mode 100644 (file)
index 0000000..2d2fa5f
--- /dev/null
@@ -0,0 +1,365 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Module Name:\r
+;\r
+;   AsmFuncs.asm\r
+;\r
+; Abstract:\r
+;\r
+;   Debug interrupt handle functions.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+#include "DebugException.h"\r
+\r
+.686p\r
+.xmm\r
+.model  flat,c\r
+\r
+;\r
+; InterruptProcess()\r
+;\r
+InterruptProcess                 PROTO   C\r
+\r
+public    Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize\r
+\r
+.data\r
+\r
+ExceptionStubHeaderSize   DW    Exception1Handle - Exception0Handle\r
+CommonEntryAddr           DD    CommonEntry\r
+\r
+.code\r
+\r
+Exception0Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 0\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception1Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 1\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception2Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 2\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception3Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 3\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception4Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 4\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception5Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 5\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception6Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 6\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception7Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 7\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception8Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 8\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception9Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 9\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception10Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 10\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception11Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 11\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception12Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 12\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception13Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 13\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception14Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 14\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception15Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 15\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception16Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 16\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception17Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 17\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception18Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 18\r
+    jmp     dword ptr [CommonEntryAddr]\r
+Exception19Handle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 19\r
+    jmp     dword ptr [CommonEntryAddr]\r
+\r
+TimerInterruptHandle:\r
+    cli\r
+    push    eax\r
+    mov     eax, 32\r
+    jmp     dword ptr [CommonEntryAddr]\r
+\r
+CommonEntry:\r
+;\r
+; +---------------------+\r
+; +    EFlags           +\r
+; +---------------------+\r
+; +    CS               +\r
+; +---------------------+\r
+; +    EIP              +\r
+; +---------------------+\r
+; +    Error Code       +\r
+; +---------------------+\r
+; + EAX / Vector Number +\r
+; +---------------------+\r
+; +    EBP              +\r
+; +---------------------+ <-- EBP\r
+;\r
+    cmp     eax, DEBUG_EXCEPT_DOUBLE_FAULT\r
+    je      NoExtrPush\r
+    cmp     eax, DEBUG_EXCEPT_INVALID_TSS\r
+    je      NoExtrPush\r
+    cmp     eax, DEBUG_EXCEPT_SEG_NOT_PRESENT\r
+    je      NoExtrPush\r
+    cmp     eax, DEBUG_EXCEPT_STACK_FAULT\r
+    je      NoExtrPush\r
+    cmp     eax, DEBUG_EXCEPT_GP_FAULT\r
+    je      NoExtrPush\r
+    cmp     eax, DEBUG_EXCEPT_PAGE_FAULT\r
+    je      NoExtrPush\r
+    cmp     eax, DEBUG_EXCEPT_ALIGNMENT_CHECK\r
+    je      NoExtrPush\r
+\r
+    push    [esp]\r
+    mov     dword ptr [esp + 4], 0\r
+\r
+NoExtrPush:\r
+\r
+    push    ebp\r
+    mov     ebp, esp        ; save esp in ebp\r
+    ;\r
+    ; Make stack 16-byte alignment to make sure save fxrstor later\r
+    ;\r
+    and     esp, 0fffffff0h\r
+    sub     esp, 12\r
+\r
+    ; store UINT32  Edi, Esi, Ebp, Ebx, Edx, Ecx, Eax;\r
+    push    dword ptr [ebp + 4]  ; original eax\r
+    push    ebx\r
+    push    ecx\r
+    push    edx\r
+    mov     ebx, eax         ; save vector in ebx\r
+    mov     eax, ebp\r
+    add     eax, 4 * 6\r
+    push    eax              ; original ESP\r
+    push    dword ptr [ebp]  ; EBP\r
+    push    esi\r
+    push    edi\r
+\r
+    ;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+    ;; insure FXSAVE/FXRSTOR is enabled in CR4...\r
+    ;; ... while we're at it, make sure DE is also enabled...\r
+    mov     eax, cr4\r
+    push    eax       ; push cr4 firstly\r
+    or      eax, 208h\r
+    mov     cr4, eax\r
+    mov     eax, cr3\r
+    push    eax\r
+    mov     eax, cr2\r
+    push    eax\r
+    push    0         ; cr0 will not saved???\r
+    mov     eax, cr0\r
+    push    eax\r
+\r
+    xor     ecx, ecx\r
+    mov     ecx, Ss\r
+    push    ecx\r
+    mov     ecx, Cs\r
+    push    ecx\r
+    mov     ecx, Ds\r
+    push    ecx\r
+    mov     ecx, Es\r
+    push    ecx\r
+    mov     ecx, Fs\r
+    push    ecx\r
+    mov     ecx, Gs\r
+    push    ecx\r
+\r
+    ;; EIP\r
+    mov     ecx, [ebp + 4 * 3] ; EIP\r
+    push    ecx\r
+\r
+    ;; UINT32  Gdtr[2], Idtr[2];\r
+    sub  esp, 8\r
+    sidt fword ptr [esp]\r
+    sub  esp, 8\r
+    sgdt fword ptr [esp]\r
+\r
+    ;; UINT32  Ldtr, Tr;\r
+    xor  eax, eax\r
+    str  ax\r
+    push eax\r
+    sldt ax\r
+    push eax\r
+\r
+    ;; EFlags\r
+    mov     ecx, [ebp + 4 * 5]\r
+    push    ecx\r
+\r
+    ;; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+    mov     eax, dr7\r
+    push    eax\r
+\r
+    ;; clear Dr7 while executing debugger itself\r
+    xor     eax, eax\r
+ ;; mov     dr7, eax\r
+\r
+    ;; Dr6\r
+    mov     eax, dr6\r
+    push    eax\r
+\r
+    ;; insure all status bits in dr6 are clear...\r
+    xor     eax, eax\r
+    mov     dr6, eax\r
+\r
+    mov     eax, dr3\r
+    push    eax\r
+    mov     eax, dr2\r
+    push    eax\r
+    mov     eax, dr1\r
+    push    eax\r
+    mov     eax, dr0\r
+    push    eax\r
+\r
+    ;; FX_SAVE_STATE_IA32 FxSaveState;\r
+    sub esp, 512\r
+    mov edi, esp\r
+    db 0fh, 0aeh, 00000111y ;fxsave [edi]\r
+\r
+    ;; Clear Direction Flag\r
+    cld\r
+       \r
+    ; call the C interrupt process function\r
+    push    esp     ; Structure\r
+    push    ebx     ; vector\r
+    call    InterruptProcess\r
+    add     esp, 8\r
+\r
+    ;; FX_SAVE_STATE_IA32 FxSaveState;\r
+    mov esi, esp\r
+    db 0fh, 0aeh, 00001110y ; fxrstor [esi]\r
+    add esp, 512\r
+\r
+    ;; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+    pop     eax\r
+    mov     dr0, eax\r
+    pop     eax\r
+    mov     dr1, eax\r
+    pop     eax\r
+    mov     dr2, eax\r
+    pop     eax\r
+    mov     dr3, eax\r
+    ;; skip restore of dr6.  We cleared dr6 during the context save.\r
+    add     esp, 4\r
+    pop     eax\r
+    mov     dr7, eax\r
+\r
+    ;; set EFlags\r
+    pop     dword ptr [ebp + 4 * 5]  ; set EFLAGS in stack\r
+\r
+    ;; UINT32  Ldtr, Tr;\r
+    ;; UINT32  Gdtr[2], Idtr[2];\r
+    ;; Best not let anyone mess with these particular registers...\r
+    add     esp, 24\r
+\r
+    ;; UINT32  Eip;\r
+    pop     dword ptr [ebp + 4 * 3]   ; set EIP in stack\r
+\r
+    ;; UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
+    ;; NOTE - modified segment registers could hang the debugger...  We\r
+    ;;        could attempt to insulate ourselves against this possibility,\r
+    ;;        but that poses risks as well.\r
+    ;;\r
+    pop     gs\r
+    pop     fs\r
+    pop     es\r
+    pop     ds\r
+    pop     dword ptr [ebp + 4 * 4]    ; set CS in stack\r
+    pop     ss\r
+\r
+    ;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+    pop     eax\r
+    mov     cr0, eax\r
+    add     esp, 4    ; skip for Cr1\r
+    pop     eax\r
+    mov     cr2, eax\r
+    pop     eax\r
+    mov     cr3, eax\r
+    pop     eax\r
+    mov     cr4, eax\r
+\r
+    ;; restore general register\r
+    pop     edi\r
+    pop     esi\r
+    pop     dword ptr [ebp]         ; save updated ebp\r
+    pop     dword ptr [ebp + 4]     ; save updated esp\r
+    pop     edx\r
+    pop     ecx\r
+    pop     ebx\r
+    pop     eax\r
+\r
+    mov     esp, ebp\r
+    pop     ebp         ; restore ebp maybe updated\r
+    pop     esp         ; restore esp maybe updated\r
+    sub     esp, 4 * 3  ; restore interupt pushced stack\r
+\r
+    iretd\r
+\r
+END\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/DebugException.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/DebugException.h
new file mode 100644 (file)
index 0000000..13a7d23
--- /dev/null
@@ -0,0 +1,36 @@
+/** @file\r
+  Exception defintions.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _DEBUG_EXCEPTION_H_\r
+#define _DEBUG_EXCEPTION_H_\r
+\r
+#define DEBUG_EXCEPT_DIVIDE_ERROR             0\r
+#define DEBUG_EXCEPT_DEBUG                    1\r
+#define DEBUG_EXCEPT_NMI                      2\r
+#define DEBUG_EXCEPT_BREAKPOINT               3\r
+#define DEBUG_EXCEPT_OVERFLOW                 4\r
+#define DEBUG_EXCEPT_BOUND                    5\r
+#define DEBUG_EXCEPT_INVALID_OPCODE           6\r
+#define DEBUG_EXCEPT_DOUBLE_FAULT             8\r
+#define DEBUG_EXCEPT_INVALID_TSS             10\r
+#define DEBUG_EXCEPT_SEG_NOT_PRESENT         11\r
+#define DEBUG_EXCEPT_STACK_FAULT             12\r
+#define DEBUG_EXCEPT_GP_FAULT                13\r
+#define DEBUG_EXCEPT_PAGE_FAULT              14\r
+#define DEBUG_EXCEPT_FP_ERROR                16\r
+#define DEBUG_EXCEPT_ALIGNMENT_CHECK         17\r
+#define DEBUG_EXCEPT_MACHINE_CHECK           18\r
+#define DEBUG_EXCEPT_SIMD                    19\r
+\r
+#endif\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c
new file mode 100644 (file)
index 0000000..3c18b86
--- /dev/null
@@ -0,0 +1,255 @@
+/** @file\r
+  Supporting functions for x64 architecture.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "DebugAgent.h"\r
+\r
+/**\r
+  Read the offset of FP / MMX / XMM registers by register index.\r
+\r
+  @param[in]  Index    Register index.\r
+  @param[out] Width    Register width returned.\r
+\r
+  @return Offset in register address range.\r
+\r
+**/\r
+UINT16\r
+ArchReadFxStatOffset (\r
+  IN  UINT8                     Index,\r
+  OUT UINT8                     *Width\r
+  )\r
+{\r
+  if (Index < SOFT_DEBUGGER_REGISTER_ST0) {\r
+    switch (Index) {\r
+    case SOFT_DEBUGGER_REGISTER_FP_FCW:\r
+      *Width = (UINT8) sizeof (UINT16);\r
+      return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Fcw);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_FSW:\r
+      *Width = (UINT8) sizeof (UINT16);\r
+      return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Fsw);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_FTW:\r
+      *Width = (UINT8) sizeof (UINT16);\r
+      return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Ftw);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_OPCODE:\r
+      *Width = (UINT8) sizeof (UINT16);\r
+      return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Opcode);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_EIP:\r
+      *Width = (UINT8) sizeof (UINTN);\r
+      return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Rip);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:\r
+      *Width = (UINT8) sizeof (UINTN);\r
+      return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, DataOffset);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_MXCSR:\r
+      *Width = (UINT8) sizeof (UINT32);\r
+      return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Mxcsr);\r
+\r
+    case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:\r
+      *Width = (UINT8) sizeof (UINT32);\r
+      return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Mxcsr_Mask);\r
+\r
+    default:\r
+      return (UINT16) (-1);\r
+    }\r
+  }\r
+\r
+  if (Index < SOFT_DEBUGGER_REGISTER_XMM0) {\r
+    *Width = 10;\r
+  } else if (Index < SOFT_DEBUGGER_REGISTER_MM0 ) {\r
+    *Width = 16;\r
+  } else {\r
+    *Width = 8;\r
+    Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;\r
+  }\r
+\r
+  return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16;\r
+}\r
+\r
+/**\r
+  Write specified register into save CPU context.\r
+\r
+  @param[in] CpuContext         Pointer to saved CPU context.\r
+  @param[in] Index              Register index value.\r
+  @param[in] Offset             Offset in register address range\r
+  @param[in] Width              Data width to read.\r
+  @param[in] RegisterBuffer     Pointer to input buffer with data.\r
+\r
+**/\r
+VOID\r
+ArchWriteRegisterBuffer (\r
+  IN DEBUG_CPU_CONTEXT               *CpuContext,\r
+  IN UINT8                           Index,\r
+  IN UINT8                           Offset,\r
+  IN UINT8                           Width,\r
+  IN UINT8                           *RegisterBuffer\r
+  )\r
+{\r
+  UINT8           *Buffer;\r
+  if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {\r
+    Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_X64_FX_SAVE_STATE) + Index * 8;\r
+  } else {\r
+    //\r
+    // If it is MMX register, adjust its index position\r
+    //\r
+    if (Index >= SOFT_DEBUGGER_REGISTER_MM0) {\r
+      Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;\r
+    }\r
+\r
+    //\r
+    // FPU/MMX/XMM registers\r
+    //\r
+    Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, &Width);\r
+  }\r
+\r
+  CopyMem (Buffer + Offset, RegisterBuffer, Width);\r
+}\r
+\r
+/**\r
+  Read register value from saved CPU context.\r
+\r
+  @param[in] CpuContext         Pointer to saved CPU context.\r
+  @param[in] Index              Register index value.\r
+  @param[in] Offset             Offset in register address range\r
+  @param[in] Width              Data width to read.\r
+\r
+  @return The address of register value.\r
+\r
+**/\r
+UINT8 *\r
+ArchReadRegisterBuffer (\r
+  IN DEBUG_CPU_CONTEXT               *CpuContext,\r
+  IN UINT8                           Index,\r
+  IN UINT8                           Offset,\r
+  IN UINT8                           *Width\r
+  )\r
+{\r
+  UINT8           *Buffer;\r
+\r
+  if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {\r
+    Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_X64_FX_SAVE_STATE) + Index * 8;\r
+    if (*Width == 0) {\r
+      *Width = (UINT8) sizeof (UINTN);\r
+    }\r
+  } else {\r
+    //\r
+    // FPU/MMX/XMM registers\r
+    //\r
+    Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, Width);\r
+  }\r
+\r
+  return Buffer;\r
+}\r
+\r
+/**\r
+  Read group register of common registers.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterGroup        Pointer to Group registers.\r
+\r
+**/\r
+VOID\r
+ReadRegisterGroup (\r
+  IN DEBUG_CPU_CONTEXT                       *CpuContext,\r
+  IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP  *RegisterGroup\r
+  )\r
+{\r
+  RegisterGroup->Cs     = (UINT16) CpuContext->Cs;\r
+  RegisterGroup->Ds     = (UINT16) CpuContext->Ds;\r
+  RegisterGroup->Es     = (UINT16) CpuContext->Es;\r
+  RegisterGroup->Fs     = (UINT16) CpuContext->Fs;\r
+  RegisterGroup->Gs     = (UINT16) CpuContext->Gs;\r
+  RegisterGroup->Ss     = (UINT16) CpuContext->Ss;\r
+  RegisterGroup->Eflags = (UINT32) CpuContext->Eflags;\r
+  RegisterGroup->Rbp    = CpuContext->Rbp;\r
+  RegisterGroup->Eip    = CpuContext->Eip;\r
+  RegisterGroup->Rsp    = CpuContext->Rsp;\r
+  RegisterGroup->Eax    = CpuContext->Rax;\r
+  RegisterGroup->Rbx    = CpuContext->Rbx;\r
+  RegisterGroup->Rcx    = CpuContext->Rcx;\r
+  RegisterGroup->Rdx    = CpuContext->Rdx;\r
+  RegisterGroup->Rsi    = CpuContext->Rsi;\r
+  RegisterGroup->Rdi    = CpuContext->Rdi;\r
+  RegisterGroup->R8     = CpuContext->R8;\r
+  RegisterGroup->R9     = CpuContext->R9;\r
+  RegisterGroup->R10    = CpuContext->R10;\r
+  RegisterGroup->R11    = CpuContext->R11;\r
+  RegisterGroup->R12    = CpuContext->R12;\r
+  RegisterGroup->R13    = CpuContext->R13;\r
+  RegisterGroup->R14    = CpuContext->R14;\r
+  RegisterGroup->R15    = CpuContext->R15;\r
+  RegisterGroup->Dr0    = CpuContext->Dr0;\r
+  RegisterGroup->Dr1    = CpuContext->Dr1;\r
+  RegisterGroup->Dr2    = CpuContext->Dr2;\r
+  RegisterGroup->Dr3    = CpuContext->Dr3;\r
+  RegisterGroup->Dr6    = CpuContext->Dr6;\r
+  RegisterGroup->Dr7    = CpuContext->Dr7;\r
+  RegisterGroup->Cr0    = CpuContext->Cr0;\r
+  RegisterGroup->Cr2    = CpuContext->Cr2;\r
+  RegisterGroup->Cr3    = CpuContext->Cr3;\r
+  RegisterGroup->Cr4    = CpuContext->Cr4;\r
+  RegisterGroup->Cr8    = CpuContext->Cr8;\r
+\r
+  CopyMem ((UINT8 *) &RegisterGroup->Xmm0[0], (UINT8 *) &CpuContext->FxSaveState.Xmm0[0], 16 * 10);\r
+}\r
+\r
+/**\r
+  Initialize IDT entries to support source level debug.\r
+\r
+**/\r
+VOID\r
+InitializeDebugIdt (\r
+  VOID\r
+  )\r
+{\r
+  IA32_IDT_GATE_DESCRIPTOR   *IdtEntry;\r
+  UINTN                      InterruptHandler;\r
+  IA32_DESCRIPTOR            IdtDescriptor;\r
+  UINTN                      Index;\r
+  UINT16                     CodeSegment;\r
+\r
+  AsmReadIdtr (&IdtDescriptor);\r
+\r
+  //\r
+  // Use current CS as the segment selector of interrupt gate in IDT\r
+  //\r
+  CodeSegment = AsmReadCs ();\r
+\r
+  IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
+\r
+  for (Index = 0; Index < 20; Index ++) {\r
+    if ((PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {\r
+      //\r
+      // If the exception is masked to be reserved, skip it\r
+      //\r
+      continue;\r
+    }\r
+    InterruptHandler = (UINTN)&Exception0Handle + Index * ExceptionStubHeaderSize;\r
+    IdtEntry[Index].Bits.OffsetLow       = (UINT16)(UINTN)InterruptHandler;\r
+    IdtEntry[Index].Bits.OffsetHigh      = (UINT16)((UINTN)InterruptHandler >> 16);\r
+    IdtEntry[Index].Bits.OffsetUpper     = (UINT32)((UINTN)InterruptHandler >> 32);\r
+    IdtEntry[Index].Bits.Selector        = CodeSegment;\r
+    IdtEntry[Index].Bits.GateType        = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
+  }\r
+\r
+  InterruptHandler = (UINTN) &TimerInterruptHandle;\r
+  IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetLow       = (UINT16)(UINTN)InterruptHandler;\r
+  IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetHigh      = (UINT16)((UINTN)InterruptHandler >> 16);\r
+  IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetUpper     = (UINT32)((UINTN)InterruptHandler >> 32);\r
+  IdtEntry[DEBUG_TIMER_VECTOR].Bits.Selector        = CodeSegment;\r
+  IdtEntry[DEBUG_TIMER_VECTOR].Bits.GateType        = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
+}\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.h
new file mode 100644 (file)
index 0000000..0b25a78
--- /dev/null
@@ -0,0 +1,31 @@
+/** @file\r
+  X64 specific defintions for debug agent library instance.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _ARCH_DEBUG_SUPPORT_H_\r
+#define _ARCH_DEBUG_SUPPORT_H_\r
+\r
+#include "ArchRegisters.h"\r
+#include "TransferProtocol.h"\r
+\r
+typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_X64          DEBUG_DATA_REPONSE_READ_REGISTER_GROUP;\r
+typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM_X64   DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM;\r
+typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE_X64  DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE;\r
+\r
+#define DEBUG_SW_BREAKPOINT_SYMBOL       0xcc\r
+\r
+#define DEBUG_ARCH_SYMBOL                DEBUG_DATA_BREAK_CPU_ARCH_X64\r
+\r
+typedef DEBUG_DATA_X64_SYSTEM_CONTEXT    DEBUG_CPU_CONTEXT;\r
+\r
+#endif\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchReadGroupRegister.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchReadGroupRegister.c
new file mode 100644 (file)
index 0000000..72d30fc
--- /dev/null
@@ -0,0 +1,259 @@
+/** @file\r
+  x64 Group registers read support functions.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "DebugAgent.h"\r
+\r
+/**\r
+  Read segment selector by register index.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterIndex        Register Index.\r
+\r
+  @return Value of segment selector.\r
+\r
+**/\r
+UINT64\r
+ReadRegisterSelectorByIndex (\r
+  IN DEBUG_CPU_CONTEXT                       *CpuContext,\r
+  IN UINT8                                   RegisterIndex\r
+  )\r
+{\r
+  IA32_DESCRIPTOR               *Ia32Descriptor;\r
+  IA32_GDT                      *Ia32Gdt;\r
+  UINT16                        Selector;\r
+  UINT32                        Data32;\r
+\r
+  Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;\r
+  Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);\r
+\r
+  Selector = 0;\r
+\r
+  switch (RegisterIndex) {\r
+  case SOFT_DEBUGGER_REGISTER_CSAS:\r
+    Selector = (UINT16) CpuContext->Cs;\r
+    break;\r
+  case SOFT_DEBUGGER_REGISTER_SSAS:\r
+    Selector = (UINT16) CpuContext->Ss;\r
+    break;\r
+  case SOFT_DEBUGGER_REGISTER_GSAS:\r
+    Selector = (UINT16) CpuContext->Gs;\r
+    break;\r
+  case SOFT_DEBUGGER_REGISTER_FSAS:\r
+    Selector = (UINT16) CpuContext->Fs;\r
+    break;\r
+  case SOFT_DEBUGGER_REGISTER_ESAS:\r
+    Selector = (UINT16) CpuContext->Es;\r
+    break;\r
+  case SOFT_DEBUGGER_REGISTER_DSAS:\r
+    Selector = (UINT16) CpuContext->Ds;\r
+  case SOFT_DEBUGGER_REGISTER_LDTAS:\r
+  case SOFT_DEBUGGER_REGISTER_TSSAS:\r
+    return 0x00820000;\r
+    break;\r
+  }\r
+\r
+  Data32 = (UINT32) RShiftU64 (Ia32Gdt[Selector / 8].Uint64, 24);\r
+  return (Data32 & (UINT32)(~0xff)) | Selector;\r
+\r
+}\r
+\r
+/**\r
+  Read group register of Segment Base.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterGroupSegBase Pointer to Group registers.\r
+\r
+**/\r
+VOID\r
+ReadRegisterGroupSegBase (\r
+  IN DEBUG_CPU_CONTEXT                              *CpuContext,\r
+  IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE *RegisterGroupSegBase\r
+  )\r
+{\r
+  IA32_DESCRIPTOR               *Ia32Descriptor;\r
+  IA32_GDT                      *Ia32Gdt;\r
+  UINTN                         Index;\r
+\r
+  Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;\r
+  Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);\r
+\r
+  Index = CpuContext->Cs / 8;\r
+  RegisterGroupSegBase->CsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+  Index = CpuContext->Ss / 8;\r
+  RegisterGroupSegBase->SsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+  Index = CpuContext->Gs / 8;\r
+  RegisterGroupSegBase->GsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+  Index = CpuContext->Fs / 8;\r
+  RegisterGroupSegBase->FsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+  Index = CpuContext->Es / 8;\r
+  RegisterGroupSegBase->EsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+  Index = CpuContext->Ds / 8;\r
+  RegisterGroupSegBase->DsBas = (Ia32Gdt[Index].Bits.BaseLow) + (Ia32Gdt[Index].Bits.BaseMid << 16) + (Ia32Gdt[Index].Bits.BaseMid << 24);\r
+\r
+  RegisterGroupSegBase->LdtBas = 0;\r
+  RegisterGroupSegBase->TssBas = 0;\r
+}\r
+\r
+/**\r
+  Read group register of Segment Limit.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] RegisterGroupSegLim  Pointer to Group registers.\r
+\r
+**/\r
+VOID\r
+ReadRegisterGroupSegLim (\r
+  IN DEBUG_CPU_CONTEXT                             *CpuContext,\r
+  IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM *RegisterGroupSegLim\r
+  )\r
+{\r
+  IA32_DESCRIPTOR               *Ia32Descriptor;\r
+  IA32_GDT                      *Ia32Gdt;\r
+  UINTN                         Index;\r
+\r
+  Ia32Descriptor = (IA32_DESCRIPTOR *) CpuContext->Gdtr;\r
+  Ia32Gdt = (IA32_GDT *) (Ia32Descriptor->Base);\r
+\r
+  Index = CpuContext->Cs / 8;\r
+  RegisterGroupSegLim->CsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->CsLim = (RegisterGroupSegLim->CsLim << 12) | 0xfff;\r
+  }\r
+\r
+  Index = CpuContext->Ss / 8;\r
+  RegisterGroupSegLim->SsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->SsLim = (RegisterGroupSegLim->SsLim << 12) | 0xfff;\r
+  }\r
+\r
+  Index = CpuContext->Gs / 8;\r
+  RegisterGroupSegLim->GsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->GsLim = (RegisterGroupSegLim->GsLim << 12) | 0xfff;\r
+  }\r
+\r
+  Index = CpuContext->Fs / 8;\r
+  RegisterGroupSegLim->FsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->FsLim = (RegisterGroupSegLim->FsLim << 12) | 0xfff;\r
+  }\r
+\r
+  Index = CpuContext->Es / 8;\r
+  RegisterGroupSegLim->EsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->EsLim = (RegisterGroupSegLim->EsLim << 12) | 0xfff;\r
+  }\r
+\r
+  Index = CpuContext->Ds / 8;\r
+  RegisterGroupSegLim->DsLim = Ia32Gdt[Index].Bits.LimitLow + (Ia32Gdt[Index].Bits.LimitHigh << 16);\r
+  if (Ia32Gdt[Index].Bits.Granularity == 1) {\r
+    RegisterGroupSegLim->DsLim = (RegisterGroupSegLim->DsLim << 12) | 0xfff;\r
+  }\r
+\r
+  RegisterGroupSegLim->LdtLim = 0xffff;\r
+  RegisterGroupSegLim->TssLim = 0xffff;\r
+}\r
+\r
+/**\r
+  Read group register by group index.\r
+\r
+  @param[in] CpuContext           Pointer to saved CPU context.\r
+  @param[in] GroupIndex           Group Index.\r
+\r
+  @retval RETURN_SUCCESS         Read successfully.\r
+  @retval RETURN_NOT_SUPPORTED   Group index cannot be supported.\r
+\r
+**/\r
+RETURN_STATUS\r
+ArchReadRegisterGroup (\r
+  IN DEBUG_CPU_CONTEXT                             *CpuContext,\r
+  IN UINT8                                         GroupIndex\r
+  )\r
+{\r
+  UINTN                                                    DataN;\r
+  DEBUG_DATA_REPONSE_READ_REGISTER_GROUP                   RegisterGroup;\r
+  DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT_BAS_LIM   RegisterGroupBasLim;\r
+  DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT_BASES_X64 RegisterGroupBases64;\r
+\r
+  switch (GroupIndex) {\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT64:\r
+    ReadRegisterGroup (CpuContext, &RegisterGroup);\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT));\r
+    break;\r
+\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_BAS_LIM64:\r
+    DataN = (UINTN) (CpuContext->Idtr[0] & 0xffff);\r
+    RegisterGroupBasLim.IdtLim = DataN;\r
+    DataN = (UINTN) (CpuContext->Gdtr[0] & 0xffff);\r
+    RegisterGroupBasLim.GdtLim = DataN;\r
+    DataN = (UINTN) RShiftU64 (CpuContext->Idtr[0], 16);\r
+    DataN |= (UINTN) LShiftU64 (CpuContext->Idtr[1], sizeof (UINTN) * 8 - 16);\r
+    RegisterGroupBasLim.IdtBas = DataN;\r
+    DataN = (UINTN) RShiftU64 (CpuContext->Gdtr[0], 16);\r
+    DataN |= (UINTN) LShiftU64 (CpuContext->Gdtr[1], sizeof (UINTN) * 8 - 16);\r
+    RegisterGroupBasLim.GdtBas = DataN;\r
+\r
+    ReadRegisterGroupSegLim (CpuContext, (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM *) &RegisterGroupBasLim.CsLim);\r
+    ReadRegisterGroupSegBase (CpuContext, (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE *) &RegisterGroupBasLim.CsBas);\r
+\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroupBasLim, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT_BAS_LIM));\r
+    break;\r
+\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_GP2_64:\r
+    ReadRegisterGroup (CpuContext, &RegisterGroup);\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup.Eflags, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_GP2));\r
+    break;\r
+\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_GP64:\r
+    ReadRegisterGroup (CpuContext, &RegisterGroup);\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup.Eax, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_GP));\r
+    break;\r
+\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_DR64:\r
+    ReadRegisterGroup (CpuContext, &RegisterGroup);\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup.Dr0, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_DR));\r
+    break;\r
+\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_SEGMENT_BASES64:\r
+    RegisterGroupBases64.Ldtr = (UINT16) CpuContext->Ldtr;\r
+    RegisterGroupBases64.Tr   = (UINT16) CpuContext->Tr;\r
+\r
+    RegisterGroupBases64.Csas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_CSAS);\r
+    RegisterGroupBases64.Ssas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_SSAS);\r
+    RegisterGroupBases64.Gsas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_GSAS);\r
+    RegisterGroupBases64.Fsas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_FSAS);\r
+    RegisterGroupBases64.Esas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_ESAS);\r
+    RegisterGroupBases64.Dsas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_DSAS);\r
+    RegisterGroupBases64.Ldtas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_LDTAS);\r
+    RegisterGroupBases64.Tssas = ReadRegisterSelectorByIndex (CpuContext, SOFT_DEBUGGER_REGISTER_TSSAS);\r
+\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroupBases64, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT_BASES_X64));\r
+    break;\r
+\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_CR64:\r
+    ReadRegisterGroup (CpuContext, &RegisterGroup);\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup.Dr7 + 8, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_CR));\r
+    break;\r
+\r
+  case SOFT_DEBUGGER_REGISTER_GROUP_XMM64:\r
+    ReadRegisterGroup (CpuContext, &RegisterGroup);\r
+    SendDataResponsePacket (CpuContext, (UINT8 *) &RegisterGroup.Dr7 + 8 * 6, (UINT16) sizeof (DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_XMM));\r
+    break;\r
+\r
+  default:\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchRegisters.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchRegisters.h
new file mode 100644 (file)
index 0000000..e7a5a33
--- /dev/null
@@ -0,0 +1,329 @@
+/** @file\r
+  X64 register defintions needed by debug transfer protocol.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _ARCH_REGISTERS_H_\r
+#define _ARCH_REGISTERS_H_\r
+\r
+///\r
+/// FXSAVE_STATE (promoted operation)\r
+/// FP / MMX / XMM registers (see fxrstor instruction definition)\r
+///\r
+typedef struct {\r
+  UINT16  Fcw;\r
+  UINT16  Fsw;\r
+  UINT16  Ftw;\r
+  UINT16  Opcode;\r
+  UINT64  Rip;\r
+  UINT64  DataOffset;\r
+  UINT32  Mxcsr;\r
+  UINT32  Mxcsr_Mask;\r
+  UINT8   St0Mm0[10];\r
+  UINT8   Reserved2[6];\r
+  UINT8   St1Mm1[10];\r
+  UINT8   Reserved3[6];\r
+  UINT8   St2Mm2[10];\r
+  UINT8   Reserved4[6];\r
+  UINT8   St3Mm3[10];\r
+  UINT8   Reserved5[6];\r
+  UINT8   St4Mm4[10];\r
+  UINT8   Reserved6[6];\r
+  UINT8   St5Mm5[10];\r
+  UINT8   Reserved7[6];\r
+  UINT8   St6Mm6[10];\r
+  UINT8   Reserved8[6];\r
+  UINT8   St7Mm7[10];\r
+  UINT8   Reserved9[6];\r
+  UINT8   Xmm0[16];\r
+  UINT8   Xmm1[16];\r
+  UINT8   Xmm2[16];\r
+  UINT8   Xmm3[16];\r
+  UINT8   Xmm4[16];\r
+  UINT8   Xmm5[16];\r
+  UINT8   Xmm6[16];\r
+  UINT8   Xmm7[16];\r
+  UINT8   Xmm8[16];\r
+  UINT8   Xmm9[16];\r
+  UINT8   Xmm10[16];\r
+  UINT8   Xmm11[16];\r
+  UINT8   Xmm12[16];\r
+  UINT8   Xmm13[16];\r
+  UINT8   Xmm14[16];\r
+  UINT8   Xmm15[16];\r
+  UINT8   Reserved11[6 * 16];\r
+} DEBUG_DATA_X64_FX_SAVE_STATE;\r
+\r
+///\r
+///  x64 processor context definition\r
+///\r
+typedef struct {\r
+  DEBUG_DATA_X64_FX_SAVE_STATE   FxSaveState;\r
+  UINT64                         Dr0;\r
+  UINT64                         Dr1;\r
+  UINT64                         Dr2;\r
+  UINT64                         Dr3;\r
+  UINT64                         Dr6;\r
+  UINT64                         Dr7;\r
+  UINT64                         Eflags;\r
+  UINT64                         Ldtr;\r
+  UINT64                         Tr;\r
+  UINT64                         Gdtr[2];\r
+  UINT64                         Idtr[2];\r
+  UINT64                         Eip;\r
+  UINT64                         Gs;\r
+  UINT64                         Fs;\r
+  UINT64                         Es;\r
+  UINT64                         Ds;\r
+  UINT64                         Cs;\r
+  UINT64                         Ss;\r
+  UINT64                         Cr0;\r
+  UINT64                         Cr1;  /* Reserved */\r
+  UINT64                         Cr2;\r
+  UINT64                         Cr3;\r
+  UINT64                         Cr4;\r
+  UINT64                         Rdi;\r
+  UINT64                         Rsi;\r
+  UINT64                         Rbp;\r
+  UINT64                         Rsp;\r
+  UINT64                         Rdx;\r
+  UINT64                         Rcx;\r
+  UINT64                         Rbx;\r
+  UINT64                         Rax;\r
+  UINT64                         Cr8;\r
+  UINT64                         R8;\r
+  UINT64                         R9;\r
+  UINT64                         R10;\r
+  UINT64                         R11;\r
+  UINT64                         R12;\r
+  UINT64                         R13;\r
+  UINT64                         R14;\r
+  UINT64                         R15;\r
+} DEBUG_DATA_X64_SYSTEM_CONTEXT;\r
+\r
+\r
+///\r
+///  x64 GROUP register\r
+///\r
+typedef struct {\r
+  UINT16         Cs;\r
+  UINT16         Ds;\r
+  UINT16         Es;\r
+  UINT16         Fs;\r
+  UINT16         Gs;\r
+  UINT16         Ss;\r
+  UINT32         Eflags;\r
+  UINT64         Rbp;\r
+  UINT64         Eip;\r
+  UINT64         Rsp;\r
+  UINT64         Eax;\r
+  UINT64         Rbx;\r
+  UINT64         Rcx;\r
+  UINT64         Rdx;\r
+  UINT64         Rsi;\r
+  UINT64         Rdi;\r
+  UINT64         R8;\r
+  UINT64         R9;\r
+  UINT64         R10;\r
+  UINT64         R11;\r
+  UINT64         R12;\r
+  UINT64         R13;\r
+  UINT64         R14;\r
+  UINT64         R15;\r
+  UINT64         Dr0;\r
+  UINT64         Dr1;\r
+  UINT64         Dr2;\r
+  UINT64         Dr3;\r
+  UINT64         Dr6;\r
+  UINT64         Dr7;\r
+  UINT64         Cr0;\r
+  UINT64         Cr2;\r
+  UINT64         Cr3;\r
+  UINT64         Cr4;\r
+  UINT64         Cr8;\r
+  UINT8          Xmm0[16];\r
+  UINT8          Xmm1[16];\r
+  UINT8          Xmm2[16];\r
+  UINT8          Xmm3[16];\r
+  UINT8          Xmm4[16];\r
+  UINT8          Xmm5[16];\r
+  UINT8          Xmm6[16];\r
+  UINT8          Xmm7[16];\r
+  UINT8          Xmm8[16];\r
+  UINT8          Xmm9[16];\r
+  UINT8          Xmm10[16];\r
+  UINT8          Xmm11[16];\r
+  UINT8          Xmm12[16];\r
+  UINT8          Xmm13[16];\r
+  UINT8          Xmm14[16];\r
+  UINT8          Xmm15[16];\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_X64;\r
+\r
+///\r
+///  x64 Segment Limit GROUP register\r
+///\r
+typedef struct {\r
+  UINT64         CsLim;\r
+  UINT64         SsLim;\r
+  UINT64         GsLim;\r
+  UINT64         FsLim;\r
+  UINT64         EsLim;\r
+  UINT64         DsLim;\r
+  UINT64         LdtLim;\r
+  UINT64         TssLim;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM_X64;\r
+\r
+///\r
+///  x64 Segment Base GROUP register\r
+///\r
+typedef struct {\r
+  UINT64         CsBas;\r
+  UINT64         SsBas;\r
+  UINT64         GsBas;\r
+  UINT64         FsBas;\r
+  UINT64         EsBas;\r
+  UINT64         DsBas;\r
+  UINT64         LdtBas;\r
+  UINT64         TssBas;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE_X64;\r
+\r
+///\r
+///  x64 Segment Base/Limit GROUP register\r
+///\r
+typedef struct {\r
+  UINT64         IdtBas;\r
+  UINT64         IdtLim;\r
+  UINT64         GdtBas;\r
+  UINT64         GdtLim;\r
+  UINT64         CsLim;\r
+  UINT64         SsLim;\r
+  UINT64         GsLim;\r
+  UINT64         FsLim;\r
+  UINT64         EsLim;\r
+  UINT64         DsLim;\r
+  UINT64         LdtLim;\r
+  UINT64         TssLim;\r
+  UINT64         CsBas;\r
+  UINT64         SsBas;\r
+  UINT64         GsBas;\r
+  UINT64         FsBas;\r
+  UINT64         EsBas;\r
+  UINT64         DsBas;\r
+  UINT64         LdtBas;\r
+  UINT64         TssBas;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT_BAS_LIM;\r
+\r
+///\r
+///  x64 register GROUP register\r
+///\r
+typedef struct {\r
+  UINT32         Eflags;\r
+  UINT64         Rbp;\r
+  UINT64         Eip;\r
+  UINT64         Rsp;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_GP2;\r
+\r
+///\r
+///  x64 general register GROUP register\r
+///\r
+typedef struct {\r
+  UINT64         Eax;\r
+  UINT64         Rbx;\r
+  UINT64         Rcx;\r
+  UINT64         Rdx;\r
+  UINT64         Rsi;\r
+  UINT64         Rdi;\r
+  UINT64         R8;\r
+  UINT64         R9;\r
+  UINT64         R10;\r
+  UINT64         R11;\r
+  UINT64         R12;\r
+  UINT64         R13;\r
+  UINT64         R14;\r
+  UINT64         R15;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_GP;\r
+\r
+///\r
+///  x64 Segment GROUP register\r
+///\r
+typedef struct {\r
+  UINT16         Cs;\r
+  UINT16         Ds;\r
+  UINT16         Es;\r
+  UINT16         Fs;\r
+  UINT16         Gs;\r
+  UINT16         Ss;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT;\r
+\r
+///\r
+///  x64 Debug Register GROUP register\r
+///\r
+typedef struct {\r
+  UINT64         Dr0;\r
+  UINT64         Dr1;\r
+  UINT64         Dr2;\r
+  UINT64         Dr3;\r
+  UINT64         Dr6;\r
+  UINT64         Dr7;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_DR;\r
+\r
+///\r
+///  x64 Control Register GROUP register\r
+///\r
+typedef struct {\r
+  UINT64         Cr0;\r
+  UINT64         Cr2;\r
+  UINT64         Cr3;\r
+  UINT64         Cr4;\r
+  UINT64         Cr8;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_CR;\r
+\r
+///\r
+///  x64 XMM Register GROUP register\r
+///\r
+typedef struct {\r
+  UINT8          Xmm0[16];\r
+  UINT8          Xmm1[16];\r
+  UINT8          Xmm2[16];\r
+  UINT8          Xmm3[16];\r
+  UINT8          Xmm4[16];\r
+  UINT8          Xmm5[16];\r
+  UINT8          Xmm6[16];\r
+  UINT8          Xmm7[16];\r
+  UINT8          Xmm8[16];\r
+  UINT8          Xmm9[16];\r
+  UINT8          Xmm10[16];\r
+  UINT8          Xmm11[16];\r
+  UINT8          Xmm12[16];\r
+  UINT8          Xmm13[16];\r
+  UINT8          Xmm14[16];\r
+  UINT8          Xmm15[16];\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_XMM;\r
+\r
+///\r
+///  x64 Segment Base GROUP register\r
+///\r
+typedef struct {\r
+  UINT16         Ldtr;\r
+  UINT16         Tr;\r
+  UINT64         Csas;\r
+  UINT64         Ssas;\r
+  UINT64         Gsas;\r
+  UINT64         Fsas;\r
+  UINT64         Esas;\r
+  UINT64         Dsas;\r
+  UINT64         Ldtas;\r
+  UINT64         Tssas;\r
+} DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGMENT_BASES_X64;\r
+\r
+\r
+#endif\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S
new file mode 100644 (file)
index 0000000..0d78e7d
--- /dev/null
@@ -0,0 +1,401 @@
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# Module Name:\r
+#\r
+#   AsmFuncs.S\r
+#\r
+# Abstract:\r
+#\r
+#   Debug interrupt handle functions.\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+#include "DebugException.h"\r
+\r
+ASM_GLOBAL ASM_PFX(InterruptProcess)\r
+\r
+ASM_GLOBAL ASM_PFX(Exception0Handle)\r
+ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)\r
+ASM_GLOBAL ASM_PFX(TimerInterruptHandle)\r
+ASM_GLOBAL ASM_PFX(CommonEntry)\r
+\r
+.data
+\r
+ASM_PFX(ExceptionStubHeaderSize):  .word     ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
+\r
+\r
+.text\r
+\r
+ASM_PFX(Exception0Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $0, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception1Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $1, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception2Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $2, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception3Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $3, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception4Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $4, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception5Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $5, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception6Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $6, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception7Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $7, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception8Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $8, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception9Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $9, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception10Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $10, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception11Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $11, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception12Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $12, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception13Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $13, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception14Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $14, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception15Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $15, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception16Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $16, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception17Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $17, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception18Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $18, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+ASM_PFX(Exception19Handle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $19, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+\r
+ASM_PFX(TimerInterruptHandle):\r
+   cli\r
+   pushq %rcx\r
+   mov   $32, %rcx\r
+   jmp   ASM_PFX(CommonEntry)\r
+\r
+\r
+ASM_PFX(CommonEntry):\r
+\r
+#---------------------------------------;\r
+# CommonInterruptEntry                  ;\r
+#---------------------------------------;\r
+# The follow algorithm is used for the common interrupt routine.\r
+\r
+#\r
+# +---------------------+ <-- 16-byte aligned ensured by processor\r
+# +    Old SS           +\r
+# +---------------------+\r
+# +    Old RSP          +\r
+# +---------------------+\r
+# +    RFlags           +\r
+# +---------------------+\r
+# +    CS               +\r
+# +---------------------+\r
+# +    RIP              +\r
+# +---------------------+\r
+# +    Error Code       +\r
+# +---------------------+\r
+# + RCX / Vector Number +\r
+# +---------------------+\r
+# +    RBP              +\r
+# +---------------------+ <-- RBP, 16-byte aligned\r
+#\r
+\r
+# We need to determine if any extra data was pushed by the exception\r
+  cmpq    $DEBUG_EXCEPT_DOUBLE_FAULT, %rcx\r
+  je      NoExtrPush\r
+  cmpq    $DEBUG_EXCEPT_INVALID_TSS, %rcx\r
+  je      NoExtrPush\r
+  cmpq    $DEBUG_EXCEPT_SEG_NOT_PRESENT, %rcx\r
+  je      NoExtrPush\r
+  cmpq    $DEBUG_EXCEPT_STACK_FAULT, %rcx\r
+  je      NoExtrPush\r
+  cmpq    $DEBUG_EXCEPT_GP_FAULT, %rcx\r
+  je      NoExtrPush\r
+  cmpq    $DEBUG_EXCEPT_PAGE_FAULT, %rcx\r
+  je      NoExtrPush\r
+  cmpq    $DEBUG_EXCEPT_ALIGNMENT_CHECK, %rcx\r
+  je      NoExtrPush\r
+\r
+  pushq   (%rsp)\r
+  movq    $0, 8(%rsp)\r
+\r
+NoExtrPush:\r
+  #\r
+  # All interrupt handlers are invoked through interrupt gates, so\r
+  # IF flag automatically cleared at the entry point\r
+  pushq   %rbp\r
+  movq    %rsp, %rbp\r
+\r
+  #\r
+  # Since here the stack pointer is 16-byte aligned, so\r
+  # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
+  # is 16-byte aligned\r
+  #\r
+\r
+## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
+  pushq %r15\r
+  pushq %r14\r
+  pushq %r13\r
+  pushq %r12\r
+  pushq %r11\r
+  pushq %r10\r
+  pushq %r9\r
+  pushq %r8\r
+\r
+  movq  %cr8, %r8\r
+  pushq %r8\r
+\r
+## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+  pushq %rax\r
+  pushq %rbx\r
+  pushq 8(%rbp)      # original rcx\r
+  pushq %rdx\r
+  pushq 48(%rbp)     # original rsp\r
+  pushq (%rbp)       # original rbp\r
+  pushq %rsi\r
+  pushq %rdi\r
+\r
+## UINT64  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+  movq    %cr4, %rax\r
+  orq     $0x208, %rax\r
+  movq    %rax, %cr4\r
+  pushq   %rax\r
+  movq    %cr3, %rax\r
+  pushq   %rax\r
+  movq    %cr2, %rax\r
+  pushq   %rax\r
+  xorq    %rax, %rax\r
+  pushq   %rax\r
+  movq    %cr0, %rax\r
+  pushq   %rax\r
+\r
+## UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero\r
+  xorq     %rax, %rax      # set rax to 0\r
+  movzwq   56(%rbp), %rax\r
+#  movq     %ss, %rax\r
+  pushq    %rax\r
+  movzwq   32(%rbp), %rax\r
+#  movq     %cs, %rax\r
+  pushq    %rax\r
+  movq     %ds, %rax\r
+  pushq    %rax\r
+  movq     %es, %rax\r
+  pushq    %rax\r
+  movq     %fs, %rax\r
+  pushq    %rax\r
+  movq     %gs, %rax\r
+  pushq    %rax\r
+\r
+## UINT64  Rip;\r
+  pushq    24(%rbp)\r
+\r
+## UINT64  Gdtr[2], Idtr[2];\r
+  subq     $16, %rsp\r
+  sidt    (%rsp)\r
+  subq     $16, %rsp\r
+  sgdt    (%rsp)\r
+\r
+## UINT64  Ldtr, Tr;\r
+  xorq    %rax, %rax\r
+  strw    %ax\r
+  pushq   %rax\r
+  sldtw   %ax\r
+  pushq   %rax\r
+\r
+## UINT64  RFlags;\r
+  pushq   40(%rbp)\r
+\r
+## UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+   movq    %dr7, %rax\r
+  pushq   %rax\r
+## clear Dr7 while executing debugger itself\r
+   xorq    %rax, %rax\r
+#debug   movq    %rax, %dr7\r
+\r
+   movq    %dr6, %rax\r
+  pushq    %rax\r
+## insure all status bits in dr6 are clear...\r
+   xorq    %rax, %rax\r
+   movq    %rax, %dr6\r
+\r
+   movq    %dr3, %rax\r
+  pushq    %rax\r
+   movq    %dr2, %rax\r
+  pushq    %rax\r
+   movq    %dr1, %rax\r
+  pushq    %rax\r
+   movq    %dr0, %rax\r
+  pushq    %rax\r
+\r
+## FX_SAVE_STATE_X64 FxSaveState;\r
+   subq    $512, %rsp\r
+   movq    %rsp, %rdi\r
+   .byte   0x0f, 0xae, 0b00000111\r
+\r
+## Clear Direction Flag\r
+  cld\r
+\r
+## Prepare parameter and call\r
+#  movq    8(%rbp), %rcx\r
+   movq    %rsp, %rdx\r
+   movq    %rcx, %r15   # save vector in r15\r
+  #\r
+  # Per X64 calling convention, allocate maximum parameter stack space\r
+  # and make sure RSP is 16-byte aligned\r
+  #\r
+   subq    $(4 * 8), %rsp\r
+   call    ASM_PFX(InterruptProcess)\r
+   addq    $(4 * 8), %rsp\r
+\r
+## FX_SAVE_STATE_X64 FxSaveState;\r
+\r
+   movq    %rsp, %rsi\r
+   .byte   0x0f, 0xae, 0b00001110\r
+   addq    $512, %rsp\r
+\r
+## UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+   popq     %rax\r
+   movq     %rax, %dr0\r
+   popq     %rax\r
+   movq     %rax, %dr1\r
+   popq     %rax\r
+   movq     %rax, %dr2\r
+   popq     %rax\r
+   movq     %rax, %dr3\r
+## skip restore of dr6.  We cleared dr6 during the context save.\r
+   addq     $8, %rsp\r
+   popq     %rax\r
+   movq     %rax, %dr7\r
+\r
+## UINT64  RFlags;\r
+   popq    40(%rbp)\r
+\r
+## UINT64  Ldtr, Tr;\r
+## UINT64  Gdtr[2], Idtr[2];\r
+## Best not let anyone mess with these particular registers...\r
+   addq    $48, %rsp\r
+\r
+## UINT64  Rip;\r
+   popq    24(%rbp)\r
+\r
+## UINT64  Gs, Fs, Es, Ds, Cs, Ss;\r
+   popq     %rax\r
+  # mov     gs, rax ; not for gs\r
+   popq     %rax\r
+  # mov     fs, rax ; not for fs\r
+  # (X64 will not use fs and gs, so we do not restore it)\r
+   popq     %rax\r
+  movw    %rax, %es\r
+   popq     %rax\r
+  movw    %rax, %ds\r
+   popq     32(%rbp)\r
+   popq     56(%rbp)\r
+\r
+## UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
+   popq     %rax\r
+   movq     %rax, %cr0\r
+   addq     $8, %rsp\r
+   popq     %rax\r
+   movq     %rax, %cr2\r
+   popq     %rax\r
+   movq     %rax, %cr3\r
+   popq     %rax\r
+   movq     %rax, %cr4\r
+\r
+## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
+   popq     %rdi\r
+   popq     %rsi\r
+   addq     $8, %rsp\r
+   addq     $8, %rsp\r
+   popq     %rdx\r
+   popq     %rcx\r
+   popq     %rbx\r
+   popq     %rax\r
+\r
+   popq     %r8\r
+   movq     %r8, %cr8\r
+\r
+   popq     %r8\r
+   popq     %r9\r
+   popq     %r10\r
+   popq     %r11\r
+   popq     %r12\r
+   popq     %r13\r
+   popq     %r14\r
+   popq     %r15\r
+\r
+   movq     %rbp, %rsp\r
+   popq     %rbp\r
+   addq     $16,  %rsp\r
+   iretq\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.asm b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.asm
new file mode 100644 (file)
index 0000000..b712c42
--- /dev/null
@@ -0,0 +1,364 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution.  The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php.\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Module Name:\r
+;\r
+;   AsmFuncs.asm\r
+;\r
+; Abstract:\r
+;\r
+;   Debug interrupt handle functions.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+#include "DebugException.h"\r
+\r
+\r
+externdef InterruptProcess:near\r
+\r
+data SEGMENT\r
+\r
+public          Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize\r
+\r
+ExceptionStubHeaderSize        dw      Exception1Handle - Exception0Handle ;\r
+CommonEntryAddr                dq      CommonEntry ;\r
+\r
+.code\r
+\r
+Exception0Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 0\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception1Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 1\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception2Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 2\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception3Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 3\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception4Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 4\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception5Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 5\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception6Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 6\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception7Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 7\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception8Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 8\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception9Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 9\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception10Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 10\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception11Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 11\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception12Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 12\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception13Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 13\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception14Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 14\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception15Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 15\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception16Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 16\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception17Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 17\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception18Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 18\r
+    jmp     qword ptr [CommonEntryAddr]\r
+Exception19Handle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 19\r
+    jmp     qword ptr [CommonEntryAddr]\r
+\r
+TimerInterruptHandle:\r
+    cli\r
+    push    rcx\r
+    mov     rcx, 32\r
+    jmp     qword ptr [CommonEntryAddr]\r
+\r
+CommonEntry:\r
+    ; We need to determine if any extra data was pushed by the exception\r
+    cmp     rcx, DEBUG_EXCEPT_DOUBLE_FAULT\r
+    je      NoExtrPush\r
+    cmp     rcx, DEBUG_EXCEPT_INVALID_TSS\r
+    je      NoExtrPush\r
+    cmp     rcx, DEBUG_EXCEPT_SEG_NOT_PRESENT\r
+    je      NoExtrPush\r
+    cmp     rcx, DEBUG_EXCEPT_STACK_FAULT\r
+    je      NoExtrPush\r
+    cmp     rcx, DEBUG_EXCEPT_GP_FAULT\r
+    je      NoExtrPush\r
+    cmp     rcx, DEBUG_EXCEPT_PAGE_FAULT\r
+    je      NoExtrPush\r
+    cmp     rcx, DEBUG_EXCEPT_ALIGNMENT_CHECK\r
+    je      NoExtrPush\r
+\r
+    push    [rsp]\r
+    mov     qword ptr [rsp + 8], 0\r
+\r
+NoExtrPush:\r
+    push    rbp\r
+    mov     rbp, rsp\r
+\r
+    ; store UINT64  r8, r9, r10, r11, r12, r13, r14, r15;\r
+    push    r15\r
+    push    r14\r
+    push    r13\r
+    push    r12\r
+    push    r11\r
+    push    r10\r
+    push    r9\r
+    push    r8\r
+\r
+    mov     r8, cr8\r
+    push    r8\r
+\r
+    ; store UINT64  Rdi, Rsi, Rbp, Rsp, Rdx, Rcx, Rbx, Rax;\r
+    push    rax\r
+    push    rbx\r
+    push    qword ptr [rbp + 8]       ; original rcx\r
+    push    rdx\r
+    push    qword ptr [rbp + 6 * 8]   ; original rsp\r
+    push    qword ptr [rbp]           ; original rbp\r
+    push    rsi\r
+    push    rdi\r
+\r
+    ;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+    ;; insure FXSAVE/FXRSTOR is enabled in CR4...\r
+    ;; ... while we're at it, make sure DE is also enabled...\r
+    mov     rax, cr4\r
+    or      rax, 208h\r
+    mov     cr4, rax\r
+    push    rax\r
+    mov     rax, cr3\r
+    push    rax\r
+    mov     rax, cr2\r
+    push    rax\r
+    push    0         ; cr0 will not saved???\r
+    mov     rax, cr0\r
+    push    rax\r
+\r
+    xor     rax, rax\r
+    mov     rax, Ss\r
+    push    rax\r
+    mov     rax, Cs\r
+    push    rax\r
+    mov     rax, Ds\r
+    push    rax\r
+    mov     rax, Es\r
+    push    rax\r
+    mov     rax, Fs\r
+    push    rax\r
+    mov     rax, Gs\r
+    push    rax\r
+\r
+    ;; EIP\r
+    mov     rax, [rbp + 8 * 3] ; EIP\r
+    push    rax\r
+\r
+    ;; UINT64  Gdtr[2], Idtr[2];\r
+    sub  rsp, 16\r
+    sidt fword ptr [rsp]\r
+    sub  rsp, 16\r
+    sgdt fword ptr [rsp]\r
+\r
+    ;; UINT64  Ldtr, Tr;\r
+    xor  rax, rax\r
+    str  ax\r
+    push rax\r
+    sldt ax\r
+    push rax\r
+\r
+    ;; EFlags\r
+    mov     rax, [rbp + 8 * 5]\r
+    push    rax\r
+\r
+    ;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+    mov     rax, dr7\r
+    push    rax\r
+\r
+    ;; clear Dr7 while executing debugger itself\r
+    xor     rax, rax\r
+    mov     dr7, rax\r
+\r
+    ;; Dr6\r
+    mov     rax, dr6\r
+    push    rax\r
+\r
+    ;; insure all status bits in dr6 are clear...\r
+    xor     rax, rax\r
+    mov     dr6, rax\r
+\r
+    mov     rax, dr3\r
+    push    rax\r
+    mov     rax, dr2\r
+    push    rax\r
+    mov     rax, dr1\r
+    push    rax\r
+    mov     rax, dr0\r
+    push    rax\r
+\r
+    sub     rsp, 512\r
+    mov rdi, rsp\r
+    db 0fh, 0aeh, 00000111y ;fxsave [rdi]\r
+\r
+    ;; Clear Direction Flag\r
+    cld\r
+       \r
+    ; call the C interrupt process function\r
+    mov     rdx, rsp      ; Structure\r
+    mov     r15, rcx      ; save vector in r15\r
+    \r
+    sub     rsp, 32\r
+    call    InterruptProcess\r
+    add     rsp, 32\r
+    \r
+    mov     rsi, rsp\r
+    db 0fh, 0aeh, 00001110y ; fxrstor [rsi]\r
+    add     rsp, 512\r
+\r
+    ;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+    pop     rax\r
+    mov     dr0, rax\r
+    pop     rax\r
+    mov     dr1, rax\r
+    pop     rax\r
+    mov     dr2, rax\r
+    pop     rax\r
+    mov     dr3, rax\r
+    ;; skip restore of dr6.  We cleared dr6 during the context save.\r
+    add     rsp, 8\r
+    pop     rax\r
+    mov     dr7, rax\r
+\r
+    ;; set EFlags\r
+    pop     qword ptr [rbp + 8 * 5]\r
+\r
+    ;; UINT64  Ldtr, Tr;\r
+    ;; UINT64  Gdtr[2], Idtr[2];\r
+    ;; Best not let anyone mess with these particular registers...\r
+    add     rsp, 24 * 2\r
+\r
+    ;; UINT64  Eip;\r
+    pop     qword ptr [rbp + 8 * 3]   ; set EIP in stack\r
+\r
+    ;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;\r
+    ;; NOTE - modified segment registers could hang the debugger...  We\r
+    ;;        could attempt to insulate ourselves against this possibility,\r
+    ;;        but that poses risks as well.\r
+    ;;\r
+    pop     rax\r
+    pop     rax\r
+    pop     rax\r
+    mov     es, rax\r
+    pop     rax\r
+    mov     ds, rax\r
+    pop     qword ptr [rbp + 8 * 4]    ; Set CS in stack\r
+    pop     rax\r
+    mov     ss, rax\r
+\r
+    ;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4;\r
+    pop     rax\r
+    mov     cr0, rax\r
+    add     rsp, 8    ; skip for Cr1\r
+    pop     rax\r
+    mov     cr2, rax\r
+    pop     rax\r
+    mov     cr3, rax\r
+    pop     rax\r
+    mov     cr4, rax\r
+\r
+    ;; restore general register\r
+    pop    rdi\r
+    pop    rsi\r
+    add    rsp, 8  ; skip rbp\r
+    add    rsp, 8  ; skip rsp\r
+    pop    rdx\r
+    pop    rcx\r
+    pop    rbx\r
+    pop    rax\r
+\r
+    pop    r8\r
+    mov    cr8, r8\r
+\r
+    ; store UINT64  r8, r9, r10, r11, r12, r13, r14, r15;\r
+    pop     r8\r
+    pop     r9\r
+    pop     r10\r
+    pop     r11\r
+    pop     r12\r
+    pop     r13\r
+    pop     r14\r
+    pop     r15\r
+\r
+    mov     rsp, rbp\r
+    pop     rbp\r
+    add     rsp, 16      ; skip rcx and error code\r
+\r
+    iretq\r
+\r
+END\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/DebugException.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/DebugException.h
new file mode 100644 (file)
index 0000000..13a7d23
--- /dev/null
@@ -0,0 +1,36 @@
+/** @file\r
+  Exception defintions.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _DEBUG_EXCEPTION_H_\r
+#define _DEBUG_EXCEPTION_H_\r
+\r
+#define DEBUG_EXCEPT_DIVIDE_ERROR             0\r
+#define DEBUG_EXCEPT_DEBUG                    1\r
+#define DEBUG_EXCEPT_NMI                      2\r
+#define DEBUG_EXCEPT_BREAKPOINT               3\r
+#define DEBUG_EXCEPT_OVERFLOW                 4\r
+#define DEBUG_EXCEPT_BOUND                    5\r
+#define DEBUG_EXCEPT_INVALID_OPCODE           6\r
+#define DEBUG_EXCEPT_DOUBLE_FAULT             8\r
+#define DEBUG_EXCEPT_INVALID_TSS             10\r
+#define DEBUG_EXCEPT_SEG_NOT_PRESENT         11\r
+#define DEBUG_EXCEPT_STACK_FAULT             12\r
+#define DEBUG_EXCEPT_GP_FAULT                13\r
+#define DEBUG_EXCEPT_PAGE_FAULT              14\r
+#define DEBUG_EXCEPT_FP_ERROR                16\r
+#define DEBUG_EXCEPT_ALIGNMENT_CHECK         17\r
+#define DEBUG_EXCEPT_MACHINE_CHECK           18\r
+#define DEBUG_EXCEPT_SIMD                    19\r
+\r
+#endif\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
new file mode 100644 (file)
index 0000000..cc49dc0
--- /dev/null
@@ -0,0 +1,247 @@
+/** @file\r
+  Debug Agent library implementition for Dxe Core and Dxr modules.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "DxeDebugAgentLib.h"\r
+\r
+DEBUG_AGENT_MAILBOX          mMailbox;\r
+\r
+DEBUG_AGENT_MAILBOX          *mMailboxPointer;\r
+\r
+IA32_IDT_GATE_DESCRIPTOR     mIdtEntryTable[33];\r
+\r
+BOOLEAN                      mConfigurationTableNeeded = FALSE;\r
+\r
+CONST BOOLEAN                MultiProcessorDebugSupport = TRUE;\r
+\r
+/**\r
+  Constructor allocates the NVS memory to store Mailbox and install configuration table\r
+  in system table to store its pointer.\r
+\r
+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.\r
+  @param[in]  SystemTable   A pointer to the EFI System Table.\r
+\r
+  @retval  RETURN_SUCCESS            Allocate the global memory space to store guid and function tables.\r
+  @retval  RETURN_OUT_OF_RESOURCES   No enough memory to allocated.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+DxeDebugAgentLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_PHYSICAL_ADDRESS        Address;\r
+\r
+  if (!mConfigurationTableNeeded) {\r
+    return RETURN_SUCCESS;\r
+  }\r
+\r
+  Address = 0;\r
+  Status = gBS->AllocatePages (\r
+                  AllocateAnyPages,\r
+                  EfiACPIMemoryNVS,\r
+                  EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX)),\r
+                  &Address\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  CopyMem (\r
+    (UINT8 *) (UINTN) Address,\r
+    (UINT8 *) (UINTN) mMailboxPointer,\r
+    sizeof (DEBUG_AGENT_MAILBOX)\r
+    );\r
+\r
+  mMailboxPointer = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;\r
+\r
+  return gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer);\r
+}\r
+\r
+/**\r
+  Get the pointer to Mailbox from the GUIDed HOB.\r
+\r
+  @param[in]  HobStart      The starting HOB pointer to search from.\r
+\r
+  @return Pointer to Mailbox.\r
+\r
+**/\r
+DEBUG_AGENT_MAILBOX *\r
+GetMailboxFromHob (\r
+  IN VOID                  *HobStart\r
+  )\r
+{\r
+  EFI_HOB_GUID_TYPE        *GuidHob;\r
+\r
+  GuidHob = GetNextGuidHob (&gEfiDebugAgentGuid, HobStart);\r
+  if (GuidHob == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  return (DEBUG_AGENT_MAILBOX *) (GET_GUID_HOB_DATA(GuidHob));\r
+}\r
+\r
+/**\r
+  Get Debug Agent Mailbox pointer.\r
+\r
+  @return Mailbox pointer.\r
+\r
+**/\r
+DEBUG_AGENT_MAILBOX *\r
+GetMailboxPointer (\r
+  VOID\r
+  )\r
+{\r
+  return mMailboxPointer;\r
+}\r
+\r
+/**\r
+  Get debug port handle.\r
+\r
+  @return Debug port handle.\r
+\r
+**/\r
+DEBUG_PORT_HANDLE\r
+GetDebugPortHandle (\r
+  VOID\r
+  )\r
+{\r
+  return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle);\r
+}\r
+\r
\r
+/**\r
+  Initialize debug agent.\r
+\r
+  This function is used to set up debug enviroment for DXE phase.\r
+\r
+  If this function is called by DXE Core, Context must be the pointer\r
+  to HOB list which will be used to get GUIDed HOB. It will enable\r
+  interrupt to support break-in feature.\r
+  If this function is called by DXE module, Context must be NULL. It\r
+  will enable interrupt to support break-in feature.\r
+\r
+  @param[in] InitFlag     Init flag is used to decide initialize process.\r
+  @param[in] Context      Context needed according to InitFlag.\r
+  @param[in] Function     Continue function called by debug agent library; it was\r
+                          optional.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeDebugAgent (\r
+  IN UINT32                InitFlag,\r
+  IN VOID                  *Context, OPTIONAL\r
+  IN DEBUG_AGENT_CONTINUE  Function  OPTIONAL\r
+  )\r
+{\r
+  DEBUG_AGENT_MAILBOX          *Mailbox;\r
+  IA32_DESCRIPTOR              Idtr;\r
+  UINT16                       IdtEntryCount;\r
+  BOOLEAN                      InterruptStatus;\r
+\r
+  if (InitFlag != DEBUG_AGENT_INIT_DXE_CORE &&\r
+      InitFlag != DEBUG_AGENT_INIT_S3 &&\r
+      InitFlag != DEBUG_AGENT_INIT_DXE_AP) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Save and disable original interrupt status\r
+  //\r
+  InterruptStatus = SaveAndDisableInterrupts ();\r
+\r
+  if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {\r
+    //\r
+    // Try to get Mailbox from GUIDed HOB.\r
+    //\r
+    mConfigurationTableNeeded = TRUE;\r
+    Mailbox = GetMailboxFromHob (Context);\r
+\r
+  } else if (InitFlag == DEBUG_AGENT_INIT_DXE_AP) {\r
+\r
+    EnableInterrupts ();\r
+\r
+    return;\r
+\r
+  } else {\r
+    //\r
+    // If it is in S3 path, needn't to install configuration table.\r
+    //\r
+    Mailbox = NULL;\r
+  }\r
+\r
+  if (Mailbox != NULL) {\r
+    //\r
+    // If Mailbox exists, copy it into one global variable.\r
+    //\r
+    CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));\r
+    mMailbox.DebugPortHandle = 0;\r
+  } else {\r
+    //\r
+    // If Mailbox not exists, used the local Mailbox.\r
+    //\r
+    ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX));\r
+  }\r
+\r
+  mMailboxPointer = &mMailbox;\r
+\r
+  //\r
+  // Get original IDT address and size.\r
+  //\r
+  AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr);\r
+  IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR));\r
+  if (IdtEntryCount < 33) {\r
+    Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1);\r
+    Idtr.Base  = (UINTN) &mIdtEntryTable;\r
+    AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr);\r
+  }\r
+\r
+  //\r
+  // Initialize the IDT table entries to support source level debug.\r
+  //\r
+  InitializeDebugIdt ();\r
+\r
+  //\r
+  // Initialize debug communication port\r
+  //\r
+  mMailboxPointer->DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize (NULL, NULL);\r
+\r
+  InitializeSpinLock (&mDebugMpContext.MpContextSpinLock);\r
+  InitializeSpinLock (&mDebugMpContext.DebugPortSpinLock);\r
\r
+  if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {\r
+    //\r
+    // Initialize Debug Timer hardware and enable interrupt.\r
+    //\r
+    InitializeDebugTimer ();\r
+    EnableInterrupts ();\r
+\r
+    return;\r
+  } else {\r
+    //\r
+    // Disable Debug Timer interrupt in S3 path.\r
+    //\r
+    SaveAndSetDebugTimerInterrupt (FALSE);\r
+\r
+    //\r
+    // Restore interrupt state.\r
+    //\r
+    SetInterruptState (InterruptStatus);\r
+  }\r
+\r
+}\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.h b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.h
new file mode 100644 (file)
index 0000000..7d78c51
--- /dev/null
@@ -0,0 +1,25 @@
+/** @file\r
+  Header file for Dxe Core Debug Agent Library instance.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _DXE_CORE_DEBUG_AGENT_LIB_H_\r
+#define _DXE_CORE_DEBUG_AGENT_LIB_H_\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include "DebugAgent.h"\r
+\r
+#endif\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
new file mode 100644 (file)
index 0000000..b932437
--- /dev/null
@@ -0,0 +1,87 @@
+## @file\r
+#  Debug Agent library instance for Dxe Core and Dxe modules.\r
+#\r
+#  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeDebugAgentLib\r
+  FILE_GUID                      = BA6BAD25-B814-4747-B0B0-0FBB61D40B90\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 0.7\r
+  LIBRARY_CLASS                  = DebugAgentLib|DXE_CORE DXE_DRIVER\r
+\r
+  CONSTRUCTOR                    = DxeDebugAgentLibConstructor\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources.common]\r
+  DxeDebugAgent/DxeDebugAgentLib.c\r
+  DxeDebugAgent/DxeDebugAgentLib.h\r
+  DebugAgentCommon/DebugAgent.c\r
+  DebugAgentCommon/DebugAgent.h\r
+  DebugAgentCommon/DebugTimer.c\r
+  DebugAgentCommon/DebugTimer.h\r
+  DebugAgentCommon/DebugMp.c\r
+  DebugAgentCommon/DebugMp.h\r
+\r
+[Sources.Ia32]\r
+  DebugAgentCommon/Ia32/AsmFuncs.S     | GCC\r
+  DebugAgentCommon/Ia32/AsmFuncs.asm   | MSFT\r
+  DebugAgentCommon/Ia32/ArchDebugSupport.h\r
+  DebugAgentCommon/Ia32/ArchDebugSupport.c\r
+  DebugAgentCommon/Ia32/ArchReadGroupRegister.c\r
+  DebugAgentCommon/Ia32/ArchRegisters.h\r
+  DebugAgentCommon/Ia32/DebugException.h\r
+\r
+[Sources.X64]\r
+  DebugAgentCommon/X64/AsmFuncs.S      | GCC\r
+  DebugAgentCommon/X64/AsmFuncs.asm    | MSFT\r
+  DebugAgentCommon/X64/ArchDebugSupport.h\r
+  DebugAgentCommon/X64/ArchDebugSupport.c\r
+  DebugAgentCommon/X64/ArchReadGroupRegister.c\r
+  DebugAgentCommon/X64/ArchRegisters.h\r
+  DebugAgentCommon/X64/DebugException.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+  SourceLevelDebugPkg/SourceLevelDebugPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  ResetSystemLib\r
+  IoLib\r
+  HobLib\r
+  DebugCommunicationLib\r
+  UefiBootServicesTableLib\r
+  UefiLib\r
+  PcdLib\r
+  SynchronizationLib\r
+  MemoryAllocationLib\r
+  LocalApicLib\r
+\r
+[Guids]\r
+  gEfiDebugAgentGuid                            ## PRODUCES ## Configuration Table\r
+  gEfiDebugAgentGuid                            ## CONSUMES ## HOB\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdFSBClock                                  ## CONSUMES\r
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger  ## CONSUMES\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c
new file mode 100644 (file)
index 0000000..0d4169c
--- /dev/null
@@ -0,0 +1,307 @@
+/** @file\r
+  SEC Core Debug Agent Library instance implementition.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "SecPeiDebugAgentLib.h"\r
+\r
+CONST BOOLEAN                MultiProcessorDebugSupport = FALSE;\r
+\r
+/**\r
+  Get pointer to Mailbox from IDT entry before memory is ready.\r
+\r
+**/\r
+VOID *\r
+GetMailboxPointerInIdtEntry (\r
+  VOID\r
+  )\r
+{\r
+  IA32_IDT_GATE_DESCRIPTOR   *IdtEntry;\r
+  IA32_DESCRIPTOR            IdtDescriptor;\r
+  UINTN                      Mailbox;\r
+\r
+  AsmReadIdtr (&IdtDescriptor);\r
+  IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
+\r
+  Mailbox = IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow + (IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16);\r
+  return (VOID *) Mailbox;\r
+}\r
+\r
+/**\r
+  Set the pointer of Mailbox into IDT entry before memory is ready.\r
+\r
+  @param[in]  Mailbox       The pointer of Mailbox.\r
+\r
+**/\r
+VOID\r
+SetMailboxPointerInIdtEntry (\r
+  IN VOID                    *Mailbox\r
+  )\r
+{\r
+  IA32_IDT_GATE_DESCRIPTOR   *IdtEntry;\r
+  IA32_DESCRIPTOR            IdtDescriptor;\r
+\r
+  AsmReadIdtr (&IdtDescriptor);\r
+  IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
+\r
+  IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow  = (UINT16)(UINTN)Mailbox;\r
+  IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)Mailbox >> 16);\r
+}\r
+\r
+/**\r
+  Get the pointer to Mailbox from IDT entry and build the Mailbox into GUIDed Hob\r
+  after memory is ready.\r
+\r
+  @return Pointer to Mailbox.\r
+\r
+**/\r
+DEBUG_AGENT_MAILBOX *\r
+BuildMailboxHob (\r
+  VOID\r
+  )\r
+{\r
+  DEBUG_AGENT_MAILBOX       *Mailbox;\r
+\r
+  Mailbox = (DEBUG_AGENT_MAILBOX *) GetMailboxPointerInIdtEntry ();\r
+\r
+  return BuildGuidDataHob (\r
+           &gEfiDebugAgentGuid,\r
+           Mailbox,\r
+           sizeof (DEBUG_AGENT_MAILBOX)\r
+           );\r
+}\r
+\r
+/**\r
+  Get Debug Agent Mailbox pointer.\r
+\r
+  @return Mailbox pointer.\r
+\r
+**/\r
+DEBUG_AGENT_MAILBOX *\r
+GetMailboxPointer (\r
+  VOID\r
+  )\r
+{\r
+  return (DEBUG_AGENT_MAILBOX *) GetMailboxPointerInIdtEntry ();\r
+}\r
+\r
+/**\r
+  Get debug port handle.\r
+\r
+  @return Debug port handle.\r
+\r
+**/\r
+DEBUG_PORT_HANDLE\r
+GetDebugPortHandle (\r
+  VOID\r
+  )\r
+{\r
+  DEBUG_AGENT_MAILBOX    *DebugAgentMailbox;\r
+  \r
+  DebugAgentMailbox = (DEBUG_AGENT_MAILBOX *)GetMailboxPointerInIdtEntry ();\r
+\r
+  return (DEBUG_PORT_HANDLE) (UINTN)(DebugAgentMailbox->DebugPortHandle);\r
+}\r
+\r
+/**\r
+  Trigger one software interrupt to debug agent to handle it.\r
+\r
+  @param Signature       Software interrupt signature.\r
+\r
+**/\r
+VOID\r
+TriggerSoftInterrupt (\r
+  UINT32                 Signature\r
+  )\r
+{\r
+  UINTN                  Dr0;\r
+  UINTN                  Dr1;\r
+\r
+  //\r
+  // Save Debug Register State\r
+  //\r
+  Dr0 = AsmReadDr0 ();\r
+  Dr1 = AsmReadDr1 ();\r
+\r
+  //\r
+  // DR0 = Signature\r
+  //\r
+  AsmWriteDr0 (SOFT_INTERRUPT_SIGNATURE);\r
+  AsmWriteDr1 (Signature);\r
+\r
+  //\r
+  // Do INT3 to communicate with HOST side\r
+  //\r
+  CpuBreakpoint ();\r
+\r
+  //\r
+  // Restore Debug Register State only when Host didn't change it inside exception handler.\r
+  //   Dr registers can only be changed by setting the HW breakpoint.\r
+  //\r
+  AsmWriteDr0 (Dr0);\r
+  AsmWriteDr1 (Dr1);\r
+\r
+}\r
+\r
+/**\r
+  Initialize debug agent.\r
+\r
+  This function is used to set up debug environment for SEC and PEI phase.\r
+\r
+  If InitFlag is DEBUG_AGENT_INIT_PREMEM_SEC, it will overirde IDT table entries\r
+  and initialize debug port. It will enable interrupt to support break-in feature.\r
+  It will set up debug agent Mailbox in cache-as-ramfrom. It will be called before\r
+  physical memory is ready.\r
+  If InitFlag is DEBUG_AGENT_INIT_POSTMEM_SEC, debug agent will build one GUIDed\r
+  HOB to copy debug agent Mailbox. It will be called after physical memory is ready.\r
+\r
+  This function is used to set up debug environment to support source level debugging.\r
+  If certain Debug Agent Library instance has to save some private data in the stack,\r
+  this function must work on the mode that doesn't return to the caller, then\r
+  the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one\r
+  function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is\r
+  responsible to invoke the passing-in function at the end of InitializeDebugAgent().\r
+\r
+  If the parameter Function is not NULL, Debug Agent Libary instance will invoke it by\r
+  passing in the Context to be its parameter.\r
+\r
+  If Function() is NULL, Debug Agent Library instance will return after setup debug\r
+  environment.\r
+\r
+  @param[in] InitFlag     Init flag is used to decide the initialize process.\r
+  @param[in] Context      Context needed according to InitFlag; it was optional.\r
+  @param[in] Function     Continue function called by debug agent library; it was\r
+                          optional.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeDebugAgent (\r
+  IN UINT32                InitFlag,\r
+  IN VOID                  *Context, OPTIONAL\r
+  IN DEBUG_AGENT_CONTINUE  Function  OPTIONAL\r
+  )\r
+{\r
+  DEBUG_AGENT_MAILBOX              *Mailbox;\r
+  DEBUG_AGENT_MAILBOX              MailboxInStack;\r
+  DEBUG_AGENT_PHASE2_CONTEXT       Phase2Context;\r
+  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  *DebugAgentContext;\r
+\r
+  if (InitFlag != DEBUG_AGENT_INIT_PREMEM_SEC &&\r
+      InitFlag != DEBUG_AGENT_INIT_POSTMEM_SEC) {\r
+    return;\r
+  }\r
+\r
+  DisableInterrupts ();\r
+\r
+  if (InitFlag == DEBUG_AGENT_INIT_POSTMEM_SEC) {\r
+\r
+    //\r
+    // Memory has been ready\r
+    //\r
+    if (IsHostConnected()) {\r
+      //\r
+      // Trigger one software interrupt to inform HOST\r
+      //\r
+      TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);\r
+    }\r
+\r
+    DebugAgentContext = (DEBUG_AGENT_CONTEXT_POSTMEM_SEC *) Context;\r
+\r
+    Mailbox = (DEBUG_AGENT_MAILBOX *) GetMailboxPointerInIdtEntry ();\r
+    Mailbox->DebugPortHandle = Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset;\r
+\r
+    Mailbox = BuildMailboxHob ();\r
+    Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->HeapMigrateOffset);\r
+\r
+    SetMailboxPointerInIdtEntry ((VOID *) Mailbox);\r
+\r
+    EnableInterrupts ();\r
+\r
+    if (Function != NULL) {\r
+      Function (Context);\r
+    }\r
+\r
+    return;\r
+\r
+  } else {\r
+\r
+    InitializeDebugIdt ();\r
+\r
+    Mailbox = &MailboxInStack;\r
+    ZeroMem ((VOID *) Mailbox, sizeof (DEBUG_AGENT_MAILBOX));\r
+\r
+    //\r
+    // Get and save debug port handle and set the length of memory block.\r
+    //\r
+    SetMailboxPointerInIdtEntry ((VOID *) Mailbox);\r
+\r
+    InitializeDebugTimer ();\r
+\r
+    Phase2Context.Context  = Context;\r
+    Phase2Context.Function = Function;\r
+    DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);\r
+\r
+    return;\r
+  }\r
+}\r
+\r
+/**\r
+  Caller provided function to be invoked at the end of DebugPortInitialize().\r
+\r
+  Refer to the descrption for DebugPortInitialize() for more details.\r
+\r
+  @param[in] Context           The first input argument of DebugPortInitialize().\r
+  @param[in] DebugPortHandle   Debug port handle created by Debug Communication Libary.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeDebugAgentPhase2 (\r
+  IN VOID                  *Context,\r
+  IN DEBUG_PORT_HANDLE     DebugPortHandle\r
+  )\r
+{\r
+  DEBUG_AGENT_PHASE2_CONTEXT *Phase2Context;\r
+  DEBUG_AGENT_MAILBOX        *Mailbox;\r
+  EFI_SEC_PEI_HAND_OFF       *SecCoreData;\r
+\r
+  Mailbox = GetMailboxPointerInIdtEntry ();\r
+  Mailbox->DebugPortHandle = (UINT64) (UINTN)DebugPortHandle;\r
+\r
+  //\r
+  // Trigger one software interrupt to inform HOST\r
+  //\r
+  TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);\r
+\r
+  //\r
+  // If Temporary RAM region is below 128 MB, then send message to \r
+  // host to disable low memory filtering.\r
+  //\r
+  Phase2Context = (DEBUG_AGENT_PHASE2_CONTEXT *) Context;\r
+  SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Phase2Context->Context;\r
+  if ((UINTN)SecCoreData->TemporaryRamBase < BASE_128MB) {\r
+    TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);\r
+  }\r
+\r
+  //\r
+  // Enable CPU interrupts so debug timer interrupts can be delivered\r
+  //\r
+  EnableInterrupts ();\r
+\r
+  //\r
+  // Call continuation function is it is not NULL.\r
+  //\r
+  if (Phase2Context->Function != NULL) {\r
+    Phase2Context->Function (Phase2Context->Context);\r
+  }\r
+}\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.h b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.h
new file mode 100644 (file)
index 0000000..9ca5e87
--- /dev/null
@@ -0,0 +1,28 @@
+/** @file\r
+  Header file for Sec Core Debug Agent Library instance.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _SEC_CORE_DEBUG_AGENT_LIB_H_\r
+#define _SEC_CORE_DEBUG_AGENT_LIB_H_\r
+\r
+#include <PiPei.h>\r
+\r
+#include "DebugAgent.h"\r
+\r
+typedef struct {\r
+  VOID                    *Context;\r
+  DEBUG_AGENT_CONTINUE    Function;\r
+} DEBUG_AGENT_PHASE2_CONTEXT;\r
+\r
+#endif\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
new file mode 100644 (file)
index 0000000..e2b8ad6
--- /dev/null
@@ -0,0 +1,81 @@
+## @file\r
+#  Debug Agent library instance for SEC Core and PEI modules.\r
+#\r
+#  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SecPeiDebugAgentLib\r
+  FILE_GUID                      = 508B7D59-CD4E-4a6b-A45B-6D3B2D90111E\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 0.7\r
+  LIBRARY_CLASS                  = DebugAgentLib|SEC PEIM\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources.common]\r
+  SecPeiDebugAgent/SecPeiDebugAgentLib.c\r
+  SecPeiDebugAgent/SecPeiDebugAgentLib.h\r
+  DebugAgentCommon/DebugAgent.c\r
+  DebugAgentCommon/DebugAgent.h\r
+  DebugAgentCommon/DebugTimer.c\r
+  DebugAgentCommon/DebugTimer.h\r
+  DebugAgentCommon/DebugMp.c\r
+  DebugAgentCommon/DebugMp.h\r
+\r
+[Sources.Ia32]\r
+  DebugAgentCommon/Ia32/AsmFuncs.S     | GCC\r
+  DebugAgentCommon/Ia32/AsmFuncs.asm   | MSFT\r
+  DebugAgentCommon/Ia32/ArchDebugSupport.h\r
+  DebugAgentCommon/Ia32/ArchDebugSupport.c\r
+  DebugAgentCommon/Ia32/ArchReadGroupRegister.c\r
+  DebugAgentCommon/Ia32/ArchRegisters.h\r
+  DebugAgentCommon/Ia32/DebugException.h\r
+\r
+[Sources.X64]\r
+  DebugAgentCommon/X64/AsmFuncs.S      | GCC\r
+  DebugAgentCommon/X64/AsmFuncs.asm    | MSFT\r
+  DebugAgentCommon/X64/ArchDebugSupport.h\r
+  DebugAgentCommon/X64/ArchDebugSupport.c\r
+  DebugAgentCommon/X64/ArchReadGroupRegister.c\r
+  DebugAgentCommon/X64/ArchRegisters.h\r
+  DebugAgentCommon/X64/DebugException.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+  SourceLevelDebugPkg/SourceLevelDebugPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  ResetSystemLib\r
+  IoLib\r
+  HobLib\r
+  PcdLib\r
+  DebugCommunicationLib\r
+  SynchronizationLib\r
+  LocalApicLib\r
+\r
+[Guids]\r
+  gEfiDebugAgentGuid                            ## PRODUCES ## HOB\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdFSBClock                                  ## CONSUMES\r
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger  ## CONSUMES\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
new file mode 100644 (file)
index 0000000..fa42311
--- /dev/null
@@ -0,0 +1,157 @@
+/** @file\r
+  Debug Agent library implementition.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "SmmDebugAgentLib.h"\r
+\r
+DEBUG_AGENT_MAILBOX         *mMailboxPointer = NULL;\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED DEBUG_AGENT_MAILBOX         mLocalMailbox;\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN    mSavedDebugRegisters[6];\r
+\r
+CONST BOOLEAN                    MultiProcessorDebugSupport = FALSE;\r
+\r
+\r
+/**\r
+  Get Debug Agent Mailbox pointer.\r
+\r
+  @return Mailbox pointer.\r
+\r
+**/\r
+DEBUG_AGENT_MAILBOX *\r
+GetMailboxPointer (\r
+  VOID\r
+  )\r
+{\r
+  return mMailboxPointer;\r
+}\r
+\r
+/**\r
+  Get debug port handle.\r
+\r
+  @return Debug port handle.\r
+\r
+**/\r
+DEBUG_PORT_HANDLE\r
+GetDebugPortHandle (\r
+  VOID\r
+  )\r
+{\r
+  return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle);\r
+}\r
+\r
+/**\r
+  Store debug register when SMI exit.\r
+\r
+**/\r
+VOID\r
+SaveDebugRegister (\r
+  VOID\r
+  )\r
+{\r
+  mSavedDebugRegisters[0] = AsmReadDr0 ();\r
+  mSavedDebugRegisters[1] = AsmReadDr1 ();\r
+  mSavedDebugRegisters[2] = AsmReadDr2 ();\r
+  mSavedDebugRegisters[3] = AsmReadDr3 ();\r
+  mSavedDebugRegisters[4] = AsmReadDr6 ();\r
+  mSavedDebugRegisters[5] = AsmReadDr7 ();\r
+}\r
+\r
+/**\r
+  Restore debug register when SMI exit.\r
+\r
+**/\r
+VOID\r
+RestoreDebugRegister (\r
+  VOID\r
+  )\r
+{\r
+  AsmWriteDr7 (0);\r
+  AsmWriteDr0 (mSavedDebugRegisters[0]);\r
+  AsmWriteDr1 (mSavedDebugRegisters[1]);\r
+  AsmWriteDr2 (mSavedDebugRegisters[2]);\r
+  AsmWriteDr3 (mSavedDebugRegisters[3]);\r
+  AsmWriteDr6 (mSavedDebugRegisters[4]);\r
+  AsmWriteDr7 (mSavedDebugRegisters[5]);\r
+}\r
+\r
+/**\r
+  Initialize debug agent.\r
+\r
+  This function is used to set up debug enviroment for source level debug\r
+  in SMM code.\r
+\r
+  If InitFlag is DEBUG_AGENT_INIT_SMM, it will overirde IDT table entries\r
+  and initialize debug port. It will get debug agent Mailbox from GUIDed HOB,\r
+  it it exists, debug agent wiil copied it into the local Mailbox in SMM space.\r
+  it will overirde IDT table entries and initialize debug port. Context will be\r
+  NULL.\r
+  If InitFlag is DEBUG_AGENT_INIT_ENTER_SMI, debug agent will save Debug\r
+  Registers and get local Mailbox in SMM space. Context will be NULL.\r
+  If InitFlag is DEBUG_AGENT_INIT_EXIT_SMI, debug agent will restore Debug\r
+  Registers. Context will be NULL.\r
+\r
+  @param[in] InitFlag     Init flag is used to decide initialize process.\r
+  @param[in] Context      Context needed according to InitFlag.\r
+  @param[in] Function     Continue function called by debug agent library; it was\r
+                          optional.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeDebugAgent (\r
+  IN UINT32                InitFlag,\r
+  IN VOID                  *Context, OPTIONAL\r
+  IN DEBUG_AGENT_CONTINUE  Function  OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS               Status;\r
+  UINT64                   DebugPortHandle;\r
+\r
+  switch (InitFlag) {\r
+  case DEBUG_AGENT_INIT_SMM:\r
+    Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &mMailboxPointer);\r
+    if (EFI_ERROR (Status) || mMailboxPointer == NULL) {\r
+      ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX));\r
+      mMailboxPointer = &mLocalMailbox;\r
+    }\r
+\r
+    break;\r
+\r
+  case DEBUG_AGENT_INIT_ENTER_SMI:\r
+    SaveDebugRegister ();\r
+    InitializeDebugIdt ();\r
+\r
+    if (mMailboxPointer != NULL) {\r
+      //\r
+      // Initialize debug communication port\r
+      //\r
+      DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((DEBUG_PORT_HANDLE) (UINTN)mMailboxPointer->DebugPortHandle, NULL);\r
+      mMailboxPointer->DebugPortHandle = DebugPortHandle;\r
+\r
+      if (mMailboxPointer->DebugFlag.Bits.BreakOnNextSmi == 1) {\r
+        //\r
+        // If SMM entry break is set, SMM code will be break at here.\r
+        //\r
+        CpuBreakpoint ();\r
+      }\r
+    }\r
+    break;\r
+\r
+  case DEBUG_AGENT_INIT_EXIT_SMI:\r
+    RestoreDebugRegister ();\r
+    break;\r
+  }\r
+}\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.h b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.h
new file mode 100644 (file)
index 0000000..ccb55f8
--- /dev/null
@@ -0,0 +1,24 @@
+/** @file\r
+  Header file for Smm Debug Agent Library instance.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _SMM_DEBUG_AGENT_LIB_H_\r
+#define _SMM_DEBUG_AGENT_LIB_H_\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Library/UefiLib.h>\r
+\r
+#include "DebugAgent.h"\r
+\r
+#endif\r
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
new file mode 100644 (file)
index 0000000..9dfdec1
--- /dev/null
@@ -0,0 +1,81 @@
+## @file\r
+#  Debug Agent library instance for SMM modules.\r
+#\r
+#  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SecDebugAgentLib\r
+  FILE_GUID                      = CB07D74C-598F-4268-A5D1-644FB4A481E8\r
+  MODULE_TYPE                    = DXE_SMM_DRIVER\r
+  VERSION_STRING                 = 0.7\r
+  LIBRARY_CLASS                  = DebugAgentLib|DXE_SMM_DRIVER\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources.common]\r
+  SmmDebugAgent/SmmDebugAgentLib.c\r
+  SmmDebugAgent/SmmDebugAgentLib.h\r
+  DebugAgentCommon/DebugAgent.c\r
+  DebugAgentCommon/DebugAgent.h\r
+  DebugAgentCommon/DebugTimer.c\r
+  DebugAgentCommon/DebugTimer.h\r
+  DebugAgentCommon/DebugMp.c\r
+  DebugAgentCommon/DebugMp.h\r
+\r
+[Sources.Ia32]\r
+  DebugAgentCommon/Ia32/AsmFuncs.S     | GCC\r
+  DebugAgentCommon/Ia32/AsmFuncs.asm   | MSFT\r
+  DebugAgentCommon/Ia32/ArchDebugSupport.h\r
+  DebugAgentCommon/Ia32/ArchDebugSupport.c\r
+  DebugAgentCommon/Ia32/ArchReadGroupRegister.c\r
+  DebugAgentCommon/Ia32/ArchRegisters.h\r
+  DebugAgentCommon/Ia32/DebugException.h\r
+\r
+[Sources.X64]\r
+  DebugAgentCommon/X64/AsmFuncs.S      | GCC\r
+  DebugAgentCommon/X64/AsmFuncs.asm    | MSFT\r
+  DebugAgentCommon/X64/ArchDebugSupport.h\r
+  DebugAgentCommon/X64/ArchDebugSupport.c\r
+  DebugAgentCommon/X64/ArchReadGroupRegister.c\r
+  DebugAgentCommon/X64/ArchRegisters.h\r
+  DebugAgentCommon/X64/DebugException.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+  SourceLevelDebugPkg/SourceLevelDebugPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  ResetSystemLib\r
+  IoLib\r
+  DebugCommunicationLib\r
+  UefiLib\r
+  PcdLib\r
+  SynchronizationLib\r
+  LocalApicLib\r
+\r
+[Guids]\r
+  gEfiDebugAgentGuid                            ## CONSUMES ## Configuration Table\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdFSBClock                                  ## CONSUMES\r
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger  ## CONSUMES\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.c b/SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.c
new file mode 100644 (file)
index 0000000..ed1a35b
--- /dev/null
@@ -0,0 +1,169 @@
+/** @file\r
+  Debug Port Library implementation based on serial port.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+\r
+#include <Library/DebugCommunicationLib.h>\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/TimerLib.h>\r
+\r
+/**\r
+  Initialize the debug port.\r
+\r
+  This function will initialize debug port to get it ready for data transmition. If\r
+  certain Debug Communication Library instance has to save some private data in the\r
+  stack, this function must work on the mode that doesn't return to the caller, then\r
+  the caller needs to wrap up all rest of logic after DebugPortInitialize() into one\r
+  function and pass it into DebugPortInitialize(). DebugPortInitialize() is\r
+  responsible to invoke the passing-in funciton at the end of DebugPortInitialize().\r
+\r
+  If the paramter Function is not NULL, Debug Communication Libary instance will\r
+  invoke it by passing in the Context to be the first parameter. Debug Communication\r
+  Library instance could create one debug port handle to be the second parameter\r
+  passing into the Function. Debug Communication Library instance also could pass\r
+  NULL to be the second parameter if it doesn't create the debug port handle.\r
+\r
+  If the parameter Function is NULL, and Context is not NULL. At this time, Context\r
+  is the debug port handle created by the previous Debug Communication Library\r
+  instance.\r
+  a) If the instance can understand and continue use the private data of the previous\r
+     instance, it could return the same handle as passed in (as Context parameter).\r
+  b) If the instance does not understand, or does not want to continue use the\r
+     private data of the previous instance, it could ignore the input Context parameter\r
+     and create the new hanlde to be returned.\r
+\r
+  If Function() is NULL and Context is NULL, Debug Communication Library could create a\r
+  new handle and return it. NULL is also a valid handle to be returned.\r
+\r
+  @param[in] Context      Context needed by callback function; it was optional.\r
+  @param[in] Function     Continue function called by Debug Communication library;\r
+                          it was optional.\r
+\r
+  @return  The debug port handle created by Debug Communication Library if Function\r
+           is not NULL.\r
+\r
+**/\r
+DEBUG_PORT_HANDLE\r
+EFIAPI\r
+DebugPortInitialize (\r
+  IN VOID                 *Context,\r
+  IN DEBUG_PORT_CONTINUE  Function\r
+  )\r
+{\r
+  SerialPortInitialize ();\r
+\r
+  if (Function != NULL) {\r
+    Function (Context, NULL);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Read data from debug device and save the datas in buffer.\r
+\r
+  Reads NumberOfBytes data bytes from a debug device into the buffer\r
+  specified by Buffer. The number of bytes actually read is returned.\r
+  If the return value is less than NumberOfBytes, then the rest operation failed.\r
+  If NumberOfBytes is zero, then return 0.\r
+\r
+  @param  Handle           Debug port handle.\r
+  @param  Buffer           Pointer to the data buffer to store the data read from the debug device.\r
+  @param  NumberOfBytes    Number of bytes which will be read.\r
+  @param  Timeout          Timeout value for reading from debug device. It unit is Microsecond.\r
+\r
+  @retval 0                Read data failed, no data is to be read.\r
+  @retval >0               Actual number of bytes read from debug device.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+DebugPortReadBuffer (\r
+  IN DEBUG_PORT_HANDLE     Handle,\r
+  IN UINT8                 *Buffer,\r
+  IN UINTN                 NumberOfBytes,\r
+  IN UINTN                 Timeout\r
+  )\r
+{\r
+  UINTN                Index;\r
+  INTN                 Elapsed;\r
+\r
+  for (Index = 0; Index < NumberOfBytes; Index ++) {\r
+    Elapsed = (INTN) Timeout;\r
+    while (TRUE) {\r
+      if (SerialPortPoll () || Timeout == 0) {\r
+        SerialPortRead (Buffer + Index, 1);\r
+        break;\r
+      }\r
+      MicroSecondDelay (1000);\r
+      Elapsed -= 1000;\r
+      if (Elapsed < 0) {\r
+        return 0;\r
+      }\r
+    }\r
+  }\r
+\r
+  return NumberOfBytes;\r
+}\r
+\r
+/**\r
+  Write data from buffer to debug device.\r
+\r
+  Writes NumberOfBytes data bytes from Buffer to the debug device.\r
+  The number of bytes actually written to the debug device is returned.\r
+  If the return value is less than NumberOfBytes, then the write operation failed.\r
+  If NumberOfBytes is zero, then return 0.\r
+\r
+  @param  Handle           Debug port handle.\r
+  @param  Buffer           Pointer to the data buffer to be written.\r
+  @param  NumberOfBytes    Number of bytes to written to the debug device.\r
+\r
+  @retval 0                NumberOfBytes is 0.\r
+  @retval >0               The number of bytes written to the debug device.\r
+                           If this value is less than NumberOfBytes, then the read operation failed.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+DebugPortWriteBuffer (\r
+  IN DEBUG_PORT_HANDLE     Handle,\r
+  IN UINT8                 *Buffer,\r
+  IN UINTN                 NumberOfBytes\r
+  )\r
+{\r
+  return SerialPortWrite (Buffer, NumberOfBytes);\r
+}\r
+\r
+/**\r
+  Polls a debug device to see if there is any data waiting to be read.\r
+\r
+  Polls a debug device to see if there is any data waiting to be read.\r
+  If there is data waiting to be read from the debug device, then TRUE is returned.\r
+  If there is no data waiting to be read from the debug device, then FALSE is returned.\r
+\r
+  @param  Handle           Debug port handle.\r
+\r
+  @retval TRUE             Data is waiting to be read from the debug device.\r
+  @retval FALSE            There is no data waiting to be read from the serial device.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DebugPortPollBuffer (\r
+  IN DEBUG_PORT_HANDLE     Handle\r
+  )\r
+{\r
+  return SerialPortPoll ();\r
+}\r
+\r
diff --git a/SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf b/SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
new file mode 100644 (file)
index 0000000..dff0fc9
--- /dev/null
@@ -0,0 +1,38 @@
+## @file\r
+#  Debug Communication Library instance based on serila port.\r
+#\r
+#  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DebugCommunicationLibSerialPort\r
+  FILE_GUID                      = 8CC435C5-6330-4269-B0C3-E3BD05C86FB8\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 0.7\r
+  LIBRARY_CLASS                  = DebugCommunicationLib\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources.common]\r
+  DebugCommunicationLibSerialPort.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  SourceLevelDebugPkg/SourceLevelDebugPkg.dec\r
+\r
+[LibraryClasses]\r
+  SerialPortLib\r
+  TimerLib\r
+  \r
diff --git a/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb/DebugCommunicationLibUsb.c b/SourceLevelDebugPkg/Library/DebugCommunicationLibUsb/DebugCommunicationLibUsb.c
new file mode 100644 (file)
index 0000000..588e458
--- /dev/null
@@ -0,0 +1,1076 @@
+/** @file\r
+  Debug Port Library implementation based on usb debug port.\r
+\r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <IndustryStandard/Pci.h>\r
+#include <IndustryStandard/Usb.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/PciLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/DebugCommunicationLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.h>\r
+\r
+#define SETUP_PID            0x2D\r
+#define INPUT_PID            0x69\r
+#define OUTPUT_PID           0xE1\r
+#define ERROR_PID            0x55\r
+#define DATA0_PID            0xC3\r
+#define DATA1_PID            0x4B\r
+#define DATA2_PID            0x87\r
+#define MDATA_PID            0x0F\r
+#define ACK_PID              0xD2\r
+#define NAK_PID              0x5A\r
+#define STALL_PID            0x1E\r
+#define NYET_PID             0x96\r
+\r
+#define PCI_CAPABILITY_ID_DEBUG_PORT   0x0A\r
+#define USB_DEBUG_PORT_MAX_PACKET_SIZE 0x08\r
+\r
+#define USB_DEBUG_PORT_IN_USE     BIT10\r
+#define USB_DEBUG_PORT_ENABLE     BIT28\r
+#define USB_DEBUG_PORT_OWNER      BIT30\r
+\r
+#define USB_PORT_LINE_STATUS_LS   0x400\r
+#define USB_PORT_LINE_STATUS_MASK 0xC00\r
+\r
+//\r
+// Usb debug device descriptor, which is defined at\r
+// USB2 Debug Device Specification.\r
+//\r
+typedef struct _USB_DEBUG_PORT_DESCRIPTOR {\r
+  UINT8          Length;\r
+  UINT8          DescriptorType;\r
+  UINT8          DebugInEndpoint;\r
+  UINT8          DebugOutEndpoint;\r
+}USB_DEBUG_PORT_DESCRIPTOR;\r
+\r
+USB_DEVICE_REQUEST mGetDebugDescriptor = {\r
+  0x80,\r
+  USB_REQ_GET_DESCRIPTOR,\r
+  (UINT16)(0x0A << 8),\r
+  0x0000,\r
+  sizeof(USB_DEBUG_PORT_DESCRIPTOR)\r
+  };\r
+\r
+USB_DEVICE_REQUEST mSetDebugFeature = {\r
+  0x0,\r
+  USB_REQ_SET_FEATURE,\r
+  (UINT16)(0x06),\r
+  0x0000,\r
+  0x0\r
+  };\r
+\r
+USB_DEVICE_REQUEST mSetDebugAddress = {\r
+  0x0,\r
+  USB_REQ_SET_ADDRESS,\r
+  (UINT16)(0x7F),\r
+  0x0000,\r
+  0x0\r
+  };\r
+\r
+//\r
+// Usb debug port register file, which is defined at\r
+// EHCI Specification.\r
+//\r
+typedef struct _USB_DEBUG_PORT_REGISTER {\r
+  UINT32         ControlStatus;\r
+  UINT8          TokenPid;\r
+  UINT8          SendPid;\r
+  UINT8          ReceivedPid;\r
+  UINT8          Reserved1;\r
+  UINT8          DataBuffer[8];\r
+  UINT8          UsbEndPoint;\r
+  UINT8          UsbAddress;\r
+  UINT8          Reserved2;\r
+  UINT8          Reserved3;\r
+}USB_DEBUG_PORT_REGISTER;\r
+\r
+#pragma pack(1)\r
+//\r
+// The internal data structure of DEBUG_PORT_HANDLE, which stores some\r
+// important datum which are used across various phases.\r
+//\r
+typedef struct _USB_DEBUG_PORT_HANDLE{\r
+  //\r
+  // The usb debug port memory BAR number in EHCI configuration space.\r
+  //\r
+  UINT8        DebugPortBarNumber;\r
+  UINT8        Reserved;\r
+  //\r
+  // The offset of usb debug port registers in EHCI memory range.\r
+  //\r
+  UINT16       DebugPortOffset;\r
+  //\r
+  // The usb debug port memory BAR address.\r
+  //\r
+  UINTN        UsbDebugPortMemoryBase;\r
+  //\r
+  // The EHCI memory BAR address.\r
+  //\r
+  UINTN        EhciMemoryBase;\r
+  //\r
+  // The Bulk In endpoint toggle bit.\r
+  //\r
+  UINT8        BulkInToggle;\r
+  //\r
+  // The Bulk Out endpoint toggle bit.\r
+  //\r
+  UINT8        BulkOutToggle;\r
+  //\r
+  // The available data length in the following data buffer.\r
+  //\r
+  UINT8        DataCount;\r
+  //\r
+  // The data buffer. Maximum length is 8 bytes.\r
+  //\r
+  UINT8        Data[8];\r
+} USB_DEBUG_PORT_HANDLE;\r
+#pragma pack()\r
+\r
+//\r
+// The global variable which can be used after memory is ready.\r
+//\r
+USB_DEBUG_PORT_HANDLE     mUsbDebugPortHandle;\r
+\r
+/**\r
+  Calculate the usb debug port bar address.\r
+\r
+  @param  DebugPortOffset    Get usb debug port offset in the usb debug port memory space.\r
+  @param  DebugPortBarNumbar Get the bar number at which usb debug port is located.\r
+\r
+  @retval RETURN_UNSUPPORTED The usb host controller does not supported usb debug port capability.\r
+  @retval RETURN_SUCCESS     Get bar and offset successfully.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+CalculateUsbDebugPortBar (\r
+  OUT UINT16     *DebugPortOffset,\r
+  OUT UINT8      *DebugPortBarNumbar\r
+ )\r
+{\r
+  UINT16     PciStatus;\r
+  UINT8      CapabilityPtr;\r
+  UINT8      CapabilityId;\r
+\r
+  //\r
+  // Enable Ehci Host Controller MMIO Space.\r
+  //\r
+  PciStatus = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_PRIMARY_STATUS_OFFSET);\r
+\r
+  if ((PciStatus & EFI_PCI_STATUS_CAPABILITY) == 0) {\r
+    //\r
+    // The Pci Device Doesn't Support Capability Pointer.\r
+    //\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Get Pointer To Capability List\r
+  //\r
+  CapabilityPtr = PciRead8(PcdGet32(PcdUsbEhciPciAddress) + PCI_CAPBILITY_POINTER_OFFSET);\r
+\r
+  //\r
+  // Find Capability ID 0xA, Which Is For Debug Port\r
+  //\r
+  while (CapabilityPtr != 0) {\r
+    CapabilityId = PciRead8(PcdGet32(PcdUsbEhciPciAddress) + CapabilityPtr);\r
+    if (CapabilityId == PCI_CAPABILITY_ID_DEBUG_PORT) {\r
+      break;\r
+    }\r
+    CapabilityPtr = PciRead8(PcdGet32(PcdUsbEhciPciAddress) + CapabilityPtr + 1);\r
+  }\r
+\r
+  //\r
+  // No Debug Port Capability Found\r
+  //\r
+  if (CapabilityPtr == 0) {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Get The Base Address Of Debug Port Register In Debug Port Capability Register\r
+  //\r
+  *DebugPortOffset    = (UINT16)(PciRead16(PcdGet32(PcdUsbEhciPciAddress) + CapabilityPtr + 2) & 0x1FFF);\r
+  *DebugPortBarNumbar = (UINT8)((PciRead16(PcdGet32(PcdUsbEhciPciAddress) + CapabilityPtr + 2) >> 13) - 1);\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Do a usb IN transaction by usb debug port.\r
+\r
+  @param  DebugPortRegister        Pointer to the base address of usb debug port register interface.\r
+  @param  Buffer                   Pointer to the buffer receiving data.\r
+  @param  Length                   Number of bytes of the received data.\r
+  @param  Token                    The token PID for each USB transaction.\r
+  @param  Addr                     The usb device address for usb transaction.\r
+  @param  Ep                       The endpoint for usb transaction.\r
+  @param  DataToggle               The toggle bit used at usb transaction.\r
+\r
+  @retval RETURN_SUCCESS           The IN transaction is executed successfully.\r
+  @retval RETURN_INVALID_PARAMETER The parameters passed in are invalid.\r
+  @retval RETURN_DEVICE_ERROR      The IN transaction comes across error.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+UsbDebugPortIn (\r
+  IN      USB_DEBUG_PORT_REGISTER         *DebugPortRegister,\r
+  IN  OUT UINT8                           *Buffer,\r
+      OUT UINT8                           *Length,\r
+  IN      UINT8                           Token,\r
+  IN      UINT8                           Addr,\r
+  IN      UINT8                           Ep,\r
+  IN      UINT8                           DataToggle\r
+  )\r
+{\r
+  UINTN                   Index;\r
+\r
+  if (Length == NULL) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+  *Length = 0;\r
+\r
+  DebugPortRegister->TokenPid = Token;\r
+  if (DataToggle != 0) {\r
+    DebugPortRegister->SendPid = DATA1_PID;\r
+  } else {\r
+    DebugPortRegister->SendPid = DATA0_PID;\r
+  }\r
+\r
+  DebugPortRegister->UsbAddress  = (UINT8)(Addr & 0x7F);\r
+  DebugPortRegister->UsbEndPoint = (UINT8)(Ep & 0xF);\r
+\r
+  //\r
+  // Clearing W/R bit to indicate it's a READ operation\r
+  //\r
+  MmioAnd32((UINTN)&DebugPortRegister->ControlStatus, (UINT32)~BIT4);\r
+\r
+  //\r
+  // Setting GO bit as well as clearing DONE bit\r
+  //\r
+  MmioOr32((UINTN)&DebugPortRegister->ControlStatus, (UINT32)BIT5);\r
+\r
+  //\r
+  // Wait for completing the request\r
+  //\r
+  while ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & (UINT32)BIT16) == 0);\r
+\r
+  //\r
+  // Check if the request is executed successfully or not.\r
+  //\r
+  if ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus)) & BIT6) {\r
+    return RETURN_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Make sure the received data are not beyond the allowable maximum length - 8 byte\r
+  //\r
+  if (((MmioRead32((UINTN)&DebugPortRegister->ControlStatus)) & 0xF) > USB_DEBUG_PORT_MAX_PACKET_SIZE) {\r
+    return RETURN_DEVICE_ERROR;\r
+  }\r
+\r
+  *Length = (UINT8)(MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & 0xF);\r
+  for (Index = 0; Index < *Length; Index++) {\r
+    Buffer[Index] = DebugPortRegister->DataBuffer[Index];\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Do a usb SETUP/OUT transaction by usb debug port.\r
+\r
+  @param  DebugPortRegister        Pointer to the base address of usb debug port register interface.\r
+  @param  Buffer                   Pointer to the buffer receiving data.\r
+  @param  Length                   Number of bytes of the received data.\r
+  @param  Token                    The token PID for each USB transaction.\r
+  @param  Addr                     The usb device address for usb transaction.\r
+  @param  Ep                       The endpoint for usb transaction.\r
+  @param  DataToggle               The toggle bit used at usb transaction.\r
+\r
+  @retval RETURN_SUCCESS           The IN transaction is executed successfully.\r
+  @retval RETURN_INVALID_PARAMETER The parameters passed in are invalid.\r
+  @retval RETURN_DEVICE_ERROR      The IN transaction comes across error.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+UsbDebugPortOut (\r
+  IN  USB_DEBUG_PORT_REGISTER         *DebugPortRegister,\r
+  IN  UINT8                           *Buffer,\r
+  IN  UINT8                           Length,\r
+  IN  UINT8                           Token,\r
+  IN  UINT8                           Addr,\r
+  IN  UINT8                           Ep,\r
+  IN  UINT8                           DataToggle\r
+  )\r
+{\r
+  UINT8             Index;\r
+\r
+  if (Length > 8) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
+\r
+  DebugPortRegister->TokenPid = Token;\r
+  if (DataToggle != 0) {\r
+    DebugPortRegister->SendPid = DATA1_PID;\r
+  } else {\r
+    DebugPortRegister->SendPid = DATA0_PID;\r
+  }\r
+  DebugPortRegister->UsbAddress  = (UINT8)(Addr & 0x7F);\r
+  DebugPortRegister->UsbEndPoint = (UINT8)(Ep & 0xF);\r
+\r
+  //\r
+  // Fill in the data length and corresponding data.\r
+  //\r
+  MmioAnd32((UINTN)&DebugPortRegister->ControlStatus, (UINT32)~0xF);\r
+  MmioOr32((UINTN)&DebugPortRegister->ControlStatus, Length & 0xF);\r
+  for (Index = 0; Index < Length; Index++) {\r
+    DebugPortRegister->DataBuffer[Index] = Buffer[Index];\r
+  }\r
+\r
+  //\r
+  // Setting W/R bit to indicate it's a WRITE operation\r
+  //\r
+  MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT4);\r
+  //\r
+  // Setting GO bit as well as clearing DONE bit\r
+  //\r
+  MmioOr32((UINTN)&DebugPortRegister->ControlStatus, BIT5);\r
+\r
+  //\r
+  // Wait for completing the request\r
+  //\r
+  while ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus) & BIT16) == 0);\r
+\r
+  //\r
+  // Check if the request is executed successfully or not.\r
+  //\r
+  if ((MmioRead32((UINTN)&DebugPortRegister->ControlStatus)) & BIT6) {\r
+    return RETURN_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Make sure the sent data are not beyond the allowable maximum length - 8 byte\r
+  //\r
+  if (((MmioRead32((UINTN)&DebugPortRegister->ControlStatus)) & 0xF) > USB_DEBUG_PORT_MAX_PACKET_SIZE) {\r
+    return RETURN_DEVICE_ERROR;\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Do a usb control transfer by usb debug port.\r
+\r
+  @param  DebugPortRegister        Pointer to the base address of usb debug port register interface.\r
+  @param  SetupPacket              The token PID for each USB transaction.\r
+  @param  Addr                     The usb device address for usb transaction.\r
+  @param  Ep                       The endpoint for usb transaction.\r
+  @param  Data                     Pointer to the buffer receiving data.\r
+  @param  DataLength               Number of bytes of the received data.\r
+\r
+  @retval RETURN_SUCCESS           The IN transaction is executed successfully.\r
+  @retval RETURN_INVALID_PARAMETER The parameters passed in are invalid.\r
+  @retval RETURN_DEVICE_ERROR      The IN transaction comes across error.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+UsbDebugPortControlTransfer (\r
+  IN      USB_DEBUG_PORT_REGISTER         *DebugPortRegister,\r
+  IN      USB_DEVICE_REQUEST              *SetupPacket,\r
+  IN      UINT8                           Addr,\r
+  IN      UINT8                           Ep,\r
+      OUT UINT8                           *Data,\r
+  IN  OUT UINT8                           *DataLength\r
+  )\r
+{\r
+  RETURN_STATUS          Status;\r
+  UINT8                  Temp;\r
+\r
+  //\r
+  // Setup Phase\r
+  //\r
+  Status = UsbDebugPortOut(DebugPortRegister, (UINT8 *)SetupPacket, (UINT8)sizeof(USB_DEVICE_REQUEST), SETUP_PID, Addr, Ep, 0);\r
+  if (RETURN_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Data Phase\r
+  //\r
+  if (SetupPacket->Length != 0) {\r
+    if ((SetupPacket->RequestType & BIT7) != 0) {\r
+      //\r
+      // Get Data From Device\r
+      //\r
+      Status = UsbDebugPortIn(DebugPortRegister, Data, DataLength, INPUT_PID, Addr, Ep, 1);\r
+      if (RETURN_ERROR(Status)) {\r
+        return Status;\r
+      }\r
+    } else {\r
+      //\r
+      // Send Data To Device\r
+      //\r
+      Status = UsbDebugPortOut(DebugPortRegister, Data, *DataLength, OUTPUT_PID, Addr, Ep, 1);\r
+      if (RETURN_ERROR(Status)) {\r
+        return Status;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Status Phase\r
+  //\r
+  if ((SetupPacket->RequestType & BIT7) != 0) {\r
+    //\r
+    // For READ operation, Data Toggle in Status Phase Should be 1.\r
+    //\r
+    Status = UsbDebugPortOut(DebugPortRegister, NULL, 0, OUTPUT_PID, Addr, Ep, 1);\r
+  } else {\r
+    //\r
+    // For WRITE operation, Data Toggle in Status Phase Should be 1.\r
+    //\r
+    Status = UsbDebugPortIn(DebugPortRegister, NULL, &Temp, INPUT_PID, Addr, Ep, 1);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Check if it needs to re-initialize usb debug port hardware.\r
+\r
+  During different phases switch, such as SEC to PEI or PEI to DXE or DXE to SMM, we should check\r
+  whether the usb debug port hardware configuration is changed. Such case can be triggerred by\r
+  Pci bus resource allocation and so on.\r
+\r
+  @param  Handle           Debug port handle.\r
+\r
+  @retval TRUE             The usb debug port hardware configuration is changed.\r
+  @retval FALSE            The usb debug port hardware configuration is not changed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+NeedReinitializeHardware(\r
+  IN USB_DEBUG_PORT_HANDLE *Handle\r
+  )\r
+{\r
+  UINT16                  PciCmd;\r
+  UINTN                   UsbDebugPortMemoryBase;\r
+  UINTN                   EhciMemoryBase;\r
+  BOOLEAN                 Status;\r
+  USB_DEBUG_PORT_REGISTER *UsbDebugPortRegister;\r
+\r
+  Status = FALSE;\r
+\r
+  EhciMemoryBase = 0xFFFFFC00 & PciRead32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET);\r
+  if (EhciMemoryBase != Handle->EhciMemoryBase) {\r
+    Handle->EhciMemoryBase = EhciMemoryBase;\r
+    Status = TRUE;\r
+  }\r
+\r
+  UsbDebugPortMemoryBase = 0xFFFFFC00 & PciRead32(PcdGet32(PcdUsbEhciPciAddress) + PCI_BASE_ADDRESSREG_OFFSET + Handle->DebugPortBarNumber * 4);\r
+  if (UsbDebugPortMemoryBase != Handle->UsbDebugPortMemoryBase) {\r
+    Handle->UsbDebugPortMemoryBase = UsbDebugPortMemoryBase;\r
+    Status = TRUE;\r
+  }\r
+\r
+  //\r
+  // Enable Ehci Memory Space Access\r
+  //\r
+  PciCmd    = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET);\r
+  if (((PciCmd & EFI_PCI_COMMAND_MEMORY_SPACE) == 0) || ((PciCmd & EFI_PCI_COMMAND_BUS_MASTER) == 0)) {\r
+    Status = TRUE;\r
+  }\r
+\r
+  //\r
+  // Check if the debug port is enabled and owned by myself.\r
+  //\r
+  UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(Handle->UsbDebugPortMemoryBase + Handle->DebugPortOffset);\r
+  if ((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) &\r
+       (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_ENABLE | USB_DEBUG_PORT_IN_USE)) == 0) {\r
+    Status = TRUE;\r
+  }\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Initialize usb debug port hardware.\r
+\r
+  1. reset ehci host controller.\r
+  2. set right port to debug port.\r
+  3. find a usb debug device is attached by getting debug device descriptor.\r
+  4. set address for the usb debug device.\r
+  5. configure the usb debug device to debug mode.\r
+\r
+  @param  Handle           Debug port handle.\r
+\r
+  @retval TRUE             The usb debug port hardware configuration is changed.\r
+  @retval FALSE            The usb debug port hardware configuration is not changed.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+InitializeUsbDebugHardware (\r
+  IN USB_DEBUG_PORT_HANDLE *Handle\r
+)\r
+{\r
+  RETURN_STATUS             Status;\r
+  USB_DEBUG_PORT_REGISTER   *UsbDebugPortRegister;\r
+  USB_DEBUG_PORT_DESCRIPTOR UsbDebugPortDescriptor;\r
+  UINT16                    PciCmd;\r
+  UINT32                    *PortStatus;\r
+  UINT32                    *UsbCmd;\r
+  UINT32                    *UsbStatus;\r
+  UINT32                    *UsbHCSParam;\r
+  UINT8                     DebugPortNumber;\r
+  UINT8                     Length;\r
+\r
+  UsbDebugPortRegister = (USB_DEBUG_PORT_REGISTER *)(Handle->UsbDebugPortMemoryBase + Handle->DebugPortOffset);\r
+  PciCmd      = PciRead16 (PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET);\r
+  UsbHCSParam = (UINT32 *)(Handle->EhciMemoryBase + 0x04);\r
+  UsbCmd      = (UINT32 *)(Handle->EhciMemoryBase + 0x20);\r
+  UsbStatus   = (UINT32 *)(Handle->EhciMemoryBase + 0x24);\r
+\r
+  //\r
+  // initialize the data toggle used by bulk in/out endpoint.\r
+  //\r
+  Handle->BulkInToggle  = 0;\r
+  Handle->BulkOutToggle = 0;\r
+\r
+  //\r
+  // Enable Ehci Memory Space Access\r
+  //\r
+  if (((PciCmd & EFI_PCI_COMMAND_MEMORY_SPACE) == 0) || ((PciCmd & EFI_PCI_COMMAND_BUS_MASTER) == 0)) {\r
+    PciCmd |= EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER;\r
+    PciWrite16(PcdGet32(PcdUsbEhciPciAddress) + PCI_COMMAND_OFFSET, PciCmd);\r
+  }\r
+\r
+  //\r
+  // If the host controller is not halted, then halt it.\r
+  //\r
+  if ((MmioRead32((UINTN)UsbStatus) & BIT12) == 0) {\r
+    MmioAnd32((UINTN)UsbCmd, (UINT32)~BIT0);\r
+    while ((MmioRead32((UINTN)UsbStatus) & BIT12) == 0);\r
+  }\r
+  //\r
+  // reset the host controller.\r
+  //\r
+  MmioOr32((UINTN)UsbCmd, BIT1);\r
+  //\r
+  // ensure that the host controller is reset.\r
+  //\r
+  while (MmioRead32((UINTN)UsbCmd) & BIT1);\r
+\r
+  //\r
+  // Start the host controller if it's not running\r
+  //\r
+  if (MmioRead32((UINTN)UsbStatus) & BIT12) {\r
+    MmioOr32((UINTN)UsbCmd, BIT0);\r
+    // ensure that the host controller is started (HALTED bit must be cleared)\r
+    while (MmioRead32((UINTN)UsbStatus) & BIT12);\r
+  }\r
+\r
+  //\r
+  //&