]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Library/GdbDebugAgent/Ia32/Processor.c
ARM Packages: Fixed line endings
[mirror_edk2.git] / EmbeddedPkg / Library / GdbDebugAgent / Ia32 / Processor.c
index 96a1a596f3aeb9a5441013aa5bbafc2515fbc342..4e4350a0f25c0adfdbbdfa4a49ac1b48bb04e26d 100755 (executable)
-/** @file
-  Processor specific parts of the GDB stub
-
-  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-  
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
+/** @file\r
+  Processor specific parts of the GDB stub\r
+\r
+  Copyright (c) 2008 - 2009, Apple Inc. 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
+\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 <GdbDebugAgent.h>\r
-
-//
-// Array of exception types that need to be hooked by the debugger
-// {EFI mapping, GDB mapping}
-//
-EFI_EXCEPTION_TYPE_ENTRY gExceptionType[] = {
-  { EXCEPT_IA32_DIVIDE_ERROR,     GDB_SIGFPE  }, 
-  { EXCEPT_IA32_DEBUG,            GDB_SIGTRAP },
-  { EXCEPT_IA32_NMI,              GDB_SIGEMT  },
-  { EXCEPT_IA32_BREAKPOINT,       GDB_SIGTRAP },
-  { EXCEPT_IA32_OVERFLOW,         GDB_SIGSEGV },
-  { EXCEPT_IA32_BOUND,            GDB_SIGSEGV },
-  { EXCEPT_IA32_INVALID_OPCODE,   GDB_SIGILL  },
-  { EXCEPT_IA32_DOUBLE_FAULT,     GDB_SIGEMT  },
-  { EXCEPT_IA32_STACK_FAULT,      GDB_SIGSEGV },
-  { EXCEPT_IA32_GP_FAULT,         GDB_SIGSEGV },
-  { EXCEPT_IA32_PAGE_FAULT,       GDB_SIGSEGV },
-  { EXCEPT_IA32_FP_ERROR,         GDB_SIGEMT  },
-  { EXCEPT_IA32_ALIGNMENT_CHECK,  GDB_SIGEMT  },
-  { EXCEPT_IA32_MACHINE_CHECK,    GDB_SIGEMT  }
-};
-
-
-// The offsets of registers SystemContext.
-// The fields in the array are in the gdb ordering.
-//
-//16 regs
-UINTN gRegisterOffsets[] = {
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eax),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ecx),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edx),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebx),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esp),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebp),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esi),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edi),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eip),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eflags),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Cs),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ss),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ds),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Es),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Fs),
-  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Gs)
-};
-
-
-//Debug only..
-VOID 
-PrintReg (
-  IN EFI_SYSTEM_CONTEXT SystemContext
-  )
-{
-  Print ((CHAR16 *)L"EAX: %x ", SystemContext.SystemContextIa32->Eax);
-  Print ((CHAR16 *)L"ECX: %x ", SystemContext.SystemContextIa32->Ecx);
-  Print ((CHAR16 *)L"EDX: %x ", SystemContext.SystemContextIa32->Edx);
-  Print ((CHAR16 *)L"EBX: %x ", SystemContext.SystemContextIa32->Ebx);
-  Print ((CHAR16 *)L"ESP: %x ", SystemContext.SystemContextIa32->Esp);
-  Print ((CHAR16 *)L"EBP: %x ", SystemContext.SystemContextIa32->Ebp);
-  Print ((CHAR16 *)L"ESI: %x ", SystemContext.SystemContextIa32->Esi);
-  Print ((CHAR16 *)L"EDI: %x ", SystemContext.SystemContextIa32->Edi);
-  Print ((CHAR16 *)L"EIP: %x\n", SystemContext.SystemContextIa32->Eip);
-  Print ((CHAR16 *)L"EFlags: %x\n", SystemContext.SystemContextIa32->Eflags);
-}
-
-//Debug only..
-VOID 
-PrintDRreg (
-  IN EFI_SYSTEM_CONTEXT SystemContext
-  )
-{
-  Print ((CHAR16 *)L"DR0: %x ", SystemContext.SystemContextIa32->Dr0);
-  Print ((CHAR16 *)L"DR1: %x ", SystemContext.SystemContextIa32->Dr1);
-  Print ((CHAR16 *)L"DR2: %x ", SystemContext.SystemContextIa32->Dr2);
-  Print ((CHAR16 *)L"DR3: %x ", SystemContext.SystemContextIa32->Dr3);
-  Print ((CHAR16 *)L"DR6: %x ", SystemContext.SystemContextIa32->Dr6);
-  Print ((CHAR16 *)L"DR7: %x\n", SystemContext.SystemContextIa32->Dr7);
-}
-
-
-/**
- Return the number of entries in the gExceptionType[]
- @retval  UINTN, the number of entries in the gExceptionType[] array.    
- **/
-UINTN
-MaxEfiException (
-  VOID
-  )
-{
-  return sizeof (gExceptionType)/sizeof (EFI_EXCEPTION_TYPE_ENTRY);
-}
-
-
-/**
-  Check to see if the ISA is supported. 
-  ISA = Instruction Set Architecture
-  @retval TRUE if Isa is supported,
-      FALSE otherwise.
-**/
-BOOLEAN
-CheckIsa (
-  IN  EFI_INSTRUCTION_SET_ARCHITECTURE  Isa
-  )
-{
-  return (BOOLEAN)(Isa == IsaIa32);
-}
-
-
-/**
- This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering
- It is, by default, set to find the register pointer of the IA32 member
-
- @param   SystemContext     Register content at time of the exception 
- @param   RegNumber       The register to which we want to find a pointer
- @retval  the pointer to the RegNumber-th pointer
- **/
-UINTN *
-FindPointerToRegister(
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  UINTN               RegNumber  
-  )
-{
-  UINT8 *TempPtr;
-  TempPtr = ((UINT8 *)SystemContext.SystemContextIa32) + gRegisterOffsets[RegNumber];
-  return (UINTN *)TempPtr;
-}
-
-
-/**
- Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
-
- @param SystemContext     Register content at time of the exception
- @param   RegNumber       the number of the register that we want to read
- @param   OutBufPtr       pointer to the output buffer's end. the new data will be added from this point on.
- @retval  the pointer to the next character of the output buffer that is available to be written on.
- **/
-CHAR8 *
-BasicReadRegister (
-  IN  EFI_SYSTEM_CONTEXT      SystemContext,
-  IN  UINTN           RegNumber,
-  IN  CHAR8           *OutBufPtr
-  )
-{
-  UINTN RegSize;
-  
-  RegSize = 0;
-  while (RegSize < REG_SIZE) {
-    *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> (RegSize+4)) & 0xf)];
-    *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> RegSize) & 0xf)];
-    RegSize = RegSize + 8;
-  }
-  return OutBufPtr;
-}
-
-
-/** ‘p n’ 
- Reads the n-th register's value into an output buffer and sends it as a packet 
-
- @param   SystemContext   Register content at time of the exception
- @param   InBuffer      Pointer to the input buffer received from gdb server
- **/
-VOID
-EFIAPI
-ReadNthRegister (
-  IN  EFI_SYSTEM_CONTEXT   SystemContext,
-  IN  CHAR8                *InBuffer
-  )
-{
-  UINTN RegNumber;
-  CHAR8 OutBuffer[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq)
-  CHAR8 *OutBufPtr;   // pointer to the output buffer
-  
-  RegNumber = AsciiStrHexToUintn (&InBuffer[1]);
-
-  if ((RegNumber < 0) || (RegNumber >= sizeof (gRegisterOffsets)/sizeof (UINTN))) {
-    SendError (GDB_EINVALIDREGNUM);
-    return;
-  }
-
-  OutBufPtr = OutBuffer;
-  OutBufPtr = BasicReadRegister(SystemContext, RegNumber, OutBufPtr);
-
-  *OutBufPtr = '\0';  // the end of the buffer
-  SendPacket(OutBuffer);
-}
-
-
-/** ‘g’ 
- Reads the general registers into an output buffer  and sends it as a packet 
-
- @param   SystemContext     Register content at time of the exception
- **/
-VOID
-EFIAPI
-ReadGeneralRegisters (  
-  IN  EFI_SYSTEM_CONTEXT      SystemContext
-  )
-{
-  UINTN   i;
-  CHAR8 OutBuffer[129]; // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
-  CHAR8 *OutBufPtr;   // pointer to the output buffer
-
-  OutBufPtr = OutBuffer;
-  for(i = 0 ; i < sizeof (gRegisterOffsets)/sizeof (UINTN) ; i++) {  // there are only 16 registers to read   
-    OutBufPtr = BasicReadRegister(SystemContext, i, OutBufPtr);
-  }
-
-  *OutBufPtr = '\0';  // the end of the buffer
-  SendPacket(OutBuffer);
-}
-
-
-/**
- Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
-
- @param   SystemContext       Register content at time of the exception
- @param   RegNumber         the number of the register that we want to write
- @param   InBufPtr          pointer to the output buffer. the new data will be extracted from the input buffer from this point on.
- @retval  the pointer to the next character of the input buffer that can be used
- **/
-CHAR8 *
-BasicWriteRegister (
-  IN  EFI_SYSTEM_CONTEXT      SystemContext,
-  IN  UINTN           RegNumber,
-  IN  CHAR8           *InBufPtr
-  )
-{
-  UINTN RegSize;
-  UINTN TempValue; // the value transferred from a hex char
-  UINT32 NewValue; // the new value of the RegNumber-th Register
-  
-  NewValue = 0;
-  RegSize = 0;
-  while (RegSize < REG_SIZE) {
-    TempValue = HexCharToInt(*InBufPtr++);
-    
-   if (TempValue < 0) {
-      SendError (GDB_EBADMEMDATA); 
-      return NULL;
-    }
-
-    NewValue += (TempValue << (RegSize+4));
-    TempValue = HexCharToInt(*InBufPtr++);
-    
-    if (TempValue < 0) {
-      SendError (GDB_EBADMEMDATA); 
-      return NULL;
-    }
-    
-    NewValue += (TempValue << RegSize); 
-    RegSize = RegSize + 8;
-  }
-  *(FindPointerToRegister(SystemContext, RegNumber)) = NewValue;
-  return InBufPtr;
-}
-
-
-/** ‘P n...=r...’
- Writes the new value of n-th register received into the input buffer to the n-th register
-
- @param   SystemContext   Register content at time of the exception
- @param   InBuffer      Ponter to the input buffer received from gdb server
- **/
-VOID
-EFIAPI
-WriteNthRegister (
-  IN  EFI_SYSTEM_CONTEXT      SystemContext,
-  IN  CHAR8           *InBuffer
-  )
-{
-  UINTN RegNumber;
-  CHAR8 RegNumBuffer[MAX_REG_NUM_BUF_SIZE];  // put the 'n..' part of the message into this array
-  CHAR8 *RegNumBufPtr;
-  CHAR8 *InBufPtr; // pointer to the input buffer
-  
-  // find the register number to write
-  InBufPtr = &InBuffer[1];
-  RegNumBufPtr = RegNumBuffer;
-  while (*InBufPtr != '=') {
-    *RegNumBufPtr++ = *InBufPtr++;
-  } 
-  *RegNumBufPtr = '\0';
-  RegNumber = AsciiStrHexToUintn (RegNumBuffer); 
-
-  // check if this is a valid Register Number
-  if ((RegNumber < 0) || (RegNumber >= sizeof (gRegisterOffsets)/sizeof (UINTN))) {
-       SendError (GDB_EINVALIDREGNUM); 
-    return;
-  }
-  InBufPtr++;  // skips the '=' character
-  BasicWriteRegister (SystemContext, RegNumber, InBufPtr);
-  SendSuccess();
-}
-
-
-/** ‘G XX...’
- Writes the new values received into the input buffer to the general registers
-
- @param   SystemContext       Register content at time of the exception
- @param   InBuffer          Pointer to the input buffer received from gdb server
- **/
-VOID
-EFIAPI
-WriteGeneralRegisters (
-  IN  EFI_SYSTEM_CONTEXT        SystemContext,
-  IN  CHAR8             *InBuffer
-  )
-{
-  UINTN  i;
-  CHAR8 *InBufPtr; /// pointer to the input buffer
-
-  // check to see if the buffer is the right size which is 
-  // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129 
-  if (AsciiStrLen(InBuffer) != 129) { // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
-       //Bad message. Message is not the right length 
-    SendError (GDB_EBADBUFSIZE); 
-    return;
-  }
-
-  InBufPtr = &InBuffer[1];
-  
-  // Read the new values for the registers from the input buffer to an array, NewValueArray.
-  // The values in the array are in the gdb ordering
-  for(i=0; i < sizeof (gRegisterOffsets)/sizeof (UINTN); i++) {  // there are only 16 registers to write
-    InBufPtr = BasicWriteRegister(SystemContext, i, InBufPtr);
-  }
-
-  SendSuccess();
-}
-
-/** ‘c [addr ]’ 
- Continue. addr is Address to resume. If addr is omitted, resume at current 
- Address.
- @param   SystemContext     Register content at time of the exception  
- **/
-VOID
-EFIAPI
-ContinueAtAddress (
-  IN  EFI_SYSTEM_CONTEXT      SystemContext,
-  IN    CHAR8                 *PacketData
-  )
-{
-  if (PacketData[1] != '\0') {
-    SystemContext.SystemContextIa32->Eip = AsciiStrHexToUintn (&PacketData[1]);
-  } 
-}
-
-
-/** ‘s [addr ]’
- Single step. addr is the Address at which to resume. If addr is omitted, resume 
- at same Address.
- @param   SystemContext     Register content at time of the exception  
- **/
-VOID
-EFIAPI
-SingleStep (
-  IN  EFI_SYSTEM_CONTEXT      SystemContext,
-  IN    CHAR8                 *PacketData
-  )
-{
+\r
+//\r
+// Array of exception types that need to be hooked by the debugger\r
+// {EFI mapping, GDB mapping}\r
+//\r
+EFI_EXCEPTION_TYPE_ENTRY gExceptionType[] = {\r
+  { EXCEPT_IA32_DIVIDE_ERROR,     GDB_SIGFPE  }, \r
+  { EXCEPT_IA32_DEBUG,            GDB_SIGTRAP },\r
+  { EXCEPT_IA32_NMI,              GDB_SIGEMT  },\r
+  { EXCEPT_IA32_BREAKPOINT,       GDB_SIGTRAP },\r
+  { EXCEPT_IA32_OVERFLOW,         GDB_SIGSEGV },\r
+  { EXCEPT_IA32_BOUND,            GDB_SIGSEGV },\r
+  { EXCEPT_IA32_INVALID_OPCODE,   GDB_SIGILL  },\r
+  { EXCEPT_IA32_DOUBLE_FAULT,     GDB_SIGEMT  },\r
+  { EXCEPT_IA32_STACK_FAULT,      GDB_SIGSEGV },\r
+  { EXCEPT_IA32_GP_FAULT,         GDB_SIGSEGV },\r
+  { EXCEPT_IA32_PAGE_FAULT,       GDB_SIGSEGV },\r
+  { EXCEPT_IA32_FP_ERROR,         GDB_SIGEMT  },\r
+  { EXCEPT_IA32_ALIGNMENT_CHECK,  GDB_SIGEMT  },\r
+  { EXCEPT_IA32_MACHINE_CHECK,    GDB_SIGEMT  }\r
+};\r
+\r
+\r
+// The offsets of registers SystemContext.\r
+// The fields in the array are in the gdb ordering.\r
+//\r
+//16 regs\r
+UINTN gRegisterOffsets[] = {\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eax),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ecx),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edx),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebx),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esp),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebp),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esi),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edi),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eip),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eflags),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Cs),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ss),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ds),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Es),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Fs),\r
+  OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Gs)\r
+};\r
+\r
+\r
+//Debug only..\r
+VOID \r
+PrintReg (\r
+  IN EFI_SYSTEM_CONTEXT SystemContext\r
+  )\r
+{\r
+  Print ((CHAR16 *)L"EAX: %x ", SystemContext.SystemContextIa32->Eax);\r
+  Print ((CHAR16 *)L"ECX: %x ", SystemContext.SystemContextIa32->Ecx);\r
+  Print ((CHAR16 *)L"EDX: %x ", SystemContext.SystemContextIa32->Edx);\r
+  Print ((CHAR16 *)L"EBX: %x ", SystemContext.SystemContextIa32->Ebx);\r
+  Print ((CHAR16 *)L"ESP: %x ", SystemContext.SystemContextIa32->Esp);\r
+  Print ((CHAR16 *)L"EBP: %x ", SystemContext.SystemContextIa32->Ebp);\r
+  Print ((CHAR16 *)L"ESI: %x ", SystemContext.SystemContextIa32->Esi);\r
+  Print ((CHAR16 *)L"EDI: %x ", SystemContext.SystemContextIa32->Edi);\r
+  Print ((CHAR16 *)L"EIP: %x\n", SystemContext.SystemContextIa32->Eip);\r
+  Print ((CHAR16 *)L"EFlags: %x\n", SystemContext.SystemContextIa32->Eflags);\r
+}\r
+\r
+//Debug only..\r
+VOID \r
+PrintDRreg (\r
+  IN EFI_SYSTEM_CONTEXT SystemContext\r
+  )\r
+{\r
+  Print ((CHAR16 *)L"DR0: %x ", SystemContext.SystemContextIa32->Dr0);\r
+  Print ((CHAR16 *)L"DR1: %x ", SystemContext.SystemContextIa32->Dr1);\r
+  Print ((CHAR16 *)L"DR2: %x ", SystemContext.SystemContextIa32->Dr2);\r
+  Print ((CHAR16 *)L"DR3: %x ", SystemContext.SystemContextIa32->Dr3);\r
+  Print ((CHAR16 *)L"DR6: %x ", SystemContext.SystemContextIa32->Dr6);\r
+  Print ((CHAR16 *)L"DR7: %x\n", SystemContext.SystemContextIa32->Dr7);\r
+}\r
+\r
+\r
+/**\r
+ Return the number of entries in the gExceptionType[]\r
\r
+ @retval  UINTN, the number of entries in the gExceptionType[] array.    \r
+ **/\r
+UINTN\r
+MaxEfiException (\r
+  VOID\r
+  )\r
+{\r
+  return sizeof (gExceptionType)/sizeof (EFI_EXCEPTION_TYPE_ENTRY);\r
+}\r
+\r
+\r
+/**\r
+  Check to see if the ISA is supported. \r
+  ISA = Instruction Set Architecture\r
\r
+  @retval TRUE if Isa is supported,\r
+      FALSE otherwise.\r
+**/\r
+BOOLEAN\r
+CheckIsa (\r
+  IN  EFI_INSTRUCTION_SET_ARCHITECTURE  Isa\r
+  )\r
+{\r
+  return (BOOLEAN)(Isa == IsaIa32);\r
+}\r
+\r
+\r
+/**\r
+ This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering\r
+ It is, by default, set to find the register pointer of the IA32 member\r
+\r
+ @param   SystemContext     Register content at time of the exception \r
+ @param   RegNumber       The register to which we want to find a pointer\r
+ @retval  the pointer to the RegNumber-th pointer\r
+ **/\r
+UINTN *\r
+FindPointerToRegister(\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               RegNumber  \r
+  )\r
+{\r
+  UINT8 *TempPtr;\r
+  TempPtr = ((UINT8 *)SystemContext.SystemContextIa32) + gRegisterOffsets[RegNumber];\r
+  return (UINTN *)TempPtr;\r
+}\r
+\r
+\r
+/**\r
+ Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr\r
+\r
+ @param SystemContext     Register content at time of the exception\r
+ @param   RegNumber       the number of the register that we want to read\r
+ @param   OutBufPtr       pointer to the output buffer's end. the new data will be added from this point on.\r
+ @retval  the pointer to the next character of the output buffer that is available to be written on.\r
+ **/\r
+CHAR8 *\r
+BasicReadRegister (\r
+  IN  EFI_SYSTEM_CONTEXT      SystemContext,\r
+  IN  UINTN           RegNumber,\r
+  IN  CHAR8           *OutBufPtr\r
+  )\r
+{\r
+  UINTN RegSize;\r
+  \r
+  RegSize = 0;\r
+  while (RegSize < REG_SIZE) {\r
+    *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> (RegSize+4)) & 0xf)];\r
+    *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> RegSize) & 0xf)];\r
+    RegSize = RegSize + 8;\r
+  }\r
+  return OutBufPtr;\r
+}\r
+\r
+\r
+/** ‘p n’ \r
+ Reads the n-th register's value into an output buffer and sends it as a packet \r
+\r
+ @param   SystemContext   Register content at time of the exception\r
+ @param   InBuffer      Pointer to the input buffer received from gdb server\r
+ **/\r
+VOID\r
+EFIAPI\r
+ReadNthRegister (\r
+  IN  EFI_SYSTEM_CONTEXT   SystemContext,\r
+  IN  CHAR8                *InBuffer\r
+  )\r
+{\r
+  UINTN RegNumber;\r
+  CHAR8 OutBuffer[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq)\r
+  CHAR8 *OutBufPtr;   // pointer to the output buffer\r
+  \r
+  RegNumber = AsciiStrHexToUintn (&InBuffer[1]);\r
+\r
+  if ((RegNumber < 0) || (RegNumber >= sizeof (gRegisterOffsets)/sizeof (UINTN))) {\r
+    SendError (GDB_EINVALIDREGNUM);\r
+    return;\r
+  }\r
+\r
+  OutBufPtr = OutBuffer;\r
+  OutBufPtr = BasicReadRegister(SystemContext, RegNumber, OutBufPtr);\r
+\r
+  *OutBufPtr = '\0';  // the end of the buffer\r
+  SendPacket(OutBuffer);\r
+}\r
+\r
+\r
+/** ‘g’ \r
+ Reads the general registers into an output buffer  and sends it as a packet \r
+\r
+ @param   SystemContext     Register content at time of the exception\r
+ **/\r
+VOID\r
+EFIAPI\r
+ReadGeneralRegisters (  \r
+  IN  EFI_SYSTEM_CONTEXT      SystemContext\r
+  )\r
+{\r
+  UINTN   i;\r
+  CHAR8 OutBuffer[129]; // 16 regs, 8 hex chars each, and the end '\0' (escape seq)\r
+  CHAR8 *OutBufPtr;   // pointer to the output buffer\r
+\r
+  OutBufPtr = OutBuffer;\r
+  for(i = 0 ; i < sizeof (gRegisterOffsets)/sizeof (UINTN) ; i++) {  // there are only 16 registers to read   \r
+    OutBufPtr = BasicReadRegister(SystemContext, i, OutBufPtr);\r
+  }\r
+\r
+  *OutBufPtr = '\0';  // the end of the buffer\r
+  SendPacket(OutBuffer);\r
+}\r
+\r
+\r
+/**\r
+ Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr\r
+\r
+ @param   SystemContext       Register content at time of the exception\r
+ @param   RegNumber         the number of the register that we want to write\r
+ @param   InBufPtr          pointer to the output buffer. the new data will be extracted from the input buffer from this point on.\r
+ @retval  the pointer to the next character of the input buffer that can be used\r
+ **/\r
+CHAR8 *\r
+BasicWriteRegister (\r
+  IN  EFI_SYSTEM_CONTEXT      SystemContext,\r
+  IN  UINTN           RegNumber,\r
+  IN  CHAR8           *InBufPtr\r
+  )\r
+{\r
+  UINTN RegSize;\r
+  UINTN TempValue; // the value transferred from a hex char\r
+  UINT32 NewValue; // the new value of the RegNumber-th Register\r
+  \r
+  NewValue = 0;\r
+  RegSize = 0;\r
+  while (RegSize < REG_SIZE) {\r
+    TempValue = HexCharToInt(*InBufPtr++);\r
+    \r
+   if (TempValue < 0) {\r
+      SendError (GDB_EBADMEMDATA); \r
+      return NULL;\r
+    }\r
+\r
+    NewValue += (TempValue << (RegSize+4));\r
+    TempValue = HexCharToInt(*InBufPtr++);\r
+    \r
+    if (TempValue < 0) {\r
+      SendError (GDB_EBADMEMDATA); \r
+      return NULL;\r
+    }\r
+    \r
+    NewValue += (TempValue << RegSize); \r
+    RegSize = RegSize + 8;\r
+  }\r
+  *(FindPointerToRegister(SystemContext, RegNumber)) = NewValue;\r
+  return InBufPtr;\r
+}\r
+\r
+\r
+/** ‘P n...=r...’\r
+ Writes the new value of n-th register received into the input buffer to the n-th register\r
+\r
+ @param   SystemContext   Register content at time of the exception\r
+ @param   InBuffer      Ponter to the input buffer received from gdb server\r
+ **/\r
+VOID\r
+EFIAPI\r
+WriteNthRegister (\r
+  IN  EFI_SYSTEM_CONTEXT      SystemContext,\r
+  IN  CHAR8           *InBuffer\r
+  )\r
+{\r
+  UINTN RegNumber;\r
+  CHAR8 RegNumBuffer[MAX_REG_NUM_BUF_SIZE];  // put the 'n..' part of the message into this array\r
+  CHAR8 *RegNumBufPtr;\r
+  CHAR8 *InBufPtr; // pointer to the input buffer\r
+  \r
+  // find the register number to write\r
+  InBufPtr = &InBuffer[1];\r
+  RegNumBufPtr = RegNumBuffer;\r
+  while (*InBufPtr != '=') {\r
+    *RegNumBufPtr++ = *InBufPtr++;\r
+  } \r
+  *RegNumBufPtr = '\0';\r
+  RegNumber = AsciiStrHexToUintn (RegNumBuffer); \r
+\r
+  // check if this is a valid Register Number\r
+  if ((RegNumber < 0) || (RegNumber >= sizeof (gRegisterOffsets)/sizeof (UINTN))) {\r
+       SendError (GDB_EINVALIDREGNUM); \r
+    return;\r
+  }\r
+  InBufPtr++;  // skips the '=' character\r
+  BasicWriteRegister (SystemContext, RegNumber, InBufPtr);\r
+  SendSuccess();\r
+}\r
+\r
+\r
+/** ‘G XX...’\r
+ Writes the new values received into the input buffer to the general registers\r
+\r
+ @param   SystemContext       Register content at time of the exception\r
+ @param   InBuffer          Pointer to the input buffer received from gdb server\r
+ **/\r
+VOID\r
+EFIAPI\r
+WriteGeneralRegisters (\r
+  IN  EFI_SYSTEM_CONTEXT        SystemContext,\r
+  IN  CHAR8             *InBuffer\r
+  )\r
+{\r
+  UINTN  i;\r
+  CHAR8 *InBufPtr; /// pointer to the input buffer\r
+\r
+  // check to see if the buffer is the right size which is \r
+  // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129 \r
+  if (AsciiStrLen(InBuffer) != 129) { // 16 regs, 8 hex chars each, and the end '\0' (escape seq)\r
+       //Bad message. Message is not the right length \r
+    SendError (GDB_EBADBUFSIZE); \r
+    return;\r
+  }\r
+\r
+  InBufPtr = &InBuffer[1];\r
+  \r
+  // Read the new values for the registers from the input buffer to an array, NewValueArray.\r
+  // The values in the array are in the gdb ordering\r
+  for(i=0; i < sizeof (gRegisterOffsets)/sizeof (UINTN); i++) {  // there are only 16 registers to write\r
+    InBufPtr = BasicWriteRegister(SystemContext, i, InBufPtr);\r
+  }\r
+\r
+  SendSuccess();\r
+}\r
+\r
+/** ‘c [addr ]’ \r
+ Continue. addr is Address to resume. If addr is omitted, resume at current \r
+ Address.\r
\r
+ @param   SystemContext     Register content at time of the exception  \r
+ **/\r
+VOID\r
+EFIAPI\r
+ContinueAtAddress (\r
+  IN  EFI_SYSTEM_CONTEXT      SystemContext,\r
+  IN    CHAR8                 *PacketData\r
+  )\r
+{\r
+  if (PacketData[1] != '\0') {\r
+    SystemContext.SystemContextIa32->Eip = AsciiStrHexToUintn (&PacketData[1]);\r
+  } \r
+}\r
+\r
+\r
+/** ‘s [addr ]’\r
+ Single step. addr is the Address at which to resume. If addr is omitted, resume \r
+ at same Address.\r
\r
+ @param   SystemContext     Register content at time of the exception  \r
+ **/\r
+VOID\r
+EFIAPI\r
+SingleStep (\r
+  IN  EFI_SYSTEM_CONTEXT      SystemContext,\r
+  IN    CHAR8                 *PacketData\r
+  )\r
+{\r
   SendNotSupported();\r
-}
-
-
-/**
-  Returns breakpoint data address from DR0-DR3 based on the input breakpoint number
-
-  @param  SystemContext      Register content at time of the exception
-  @param  BreakpointNumber   Breakpoint number
-
-  @retval Address            Data address from DR0-DR3 based on the breakpoint number.
-
-**/
-UINTN
-GetBreakpointDataAddress (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  UINTN               BreakpointNumber
-  )
-{
-  UINTN Address;
-
-  if (BreakpointNumber == 1) {
-    Address = SystemContext.SystemContextIa32->Dr0;
-  } else if (BreakpointNumber == 2) {
-    Address = SystemContext.SystemContextIa32->Dr1;
-  } else if (BreakpointNumber == 3) {
-    Address = SystemContext.SystemContextIa32->Dr2;
-  } else if (BreakpointNumber == 4) {
-    Address = SystemContext.SystemContextIa32->Dr3;
-  } else {
-    Address = 0;
-  }
-
-  return Address;
-}
-
-
-/**
-  Returns currently detected breakpoint value based on the register DR6 B0-B3 field.
-  If no breakpoint is detected then it returns 0.
-
-  @param  SystemContext  Register content at time of the exception
-
-  @retval {1-4}          Currently detected breakpoint value   
-  @retval 0              No breakpoint detected.
-**/
-UINTN
-GetBreakpointDetected (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext
-  )
-{
-  IA32_DR6 Dr6;
-  UINTN BreakpointNumber;
-
-  Dr6.UintN = SystemContext.SystemContextIa32->Dr6;
-
-  if (Dr6.Bits.B0 == 1) {
-    BreakpointNumber = 1;
-  } else if (Dr6.Bits.B1 == 1) {
-    BreakpointNumber = 2;
-  } else if (Dr6.Bits.B2 == 1) {
-    BreakpointNumber = 3;
-  } else if (Dr6.Bits.B3 == 1) {
-    BreakpointNumber = 4;
-  } else {
-    BreakpointNumber = 0;  //No breakpoint detected 
-  }
-
-  return BreakpointNumber;
-}
-
-
-/**
-  Returns Breakpoint type (InstructionExecution, DataWrite, DataRead or DataReadWrite)
-  based on the Breakpoint number
-  
-  @param  SystemContext        Register content at time of the exception
-  @param  BreakpointNumber     Breakpoint number
-  
-  @retval BREAK_TYPE           Breakpoint type value read from register DR7 RWn field
-                               For unknown value, it returns NotSupported.
-  
-**/
-BREAK_TYPE
-GetBreakpointType (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  UINTN               BreakpointNumber
-  )
-{
-  IA32_DR7 Dr7;
-  BREAK_TYPE Type = NotSupported;  //Default is NotSupported type
-
-  Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
-  if (BreakpointNumber == 1) {
-    Type = (BREAK_TYPE) Dr7.Bits.RW0;  
-  } else if (BreakpointNumber == 2) {
-    Type = (BREAK_TYPE) Dr7.Bits.RW1;  
-  } else if (BreakpointNumber == 3) {
-    Type = (BREAK_TYPE) Dr7.Bits.RW2;  
-  } else if (BreakpointNumber == 4) {
-    Type = (BREAK_TYPE) Dr7.Bits.RW3;  
-  }
-
-  return Type;
-}
-
-
-/** 
-  Parses Length and returns the length which DR7 LENn field accepts.
-  For example: If we receive 1-Byte length then we should return 0. 
-               Zero gets written to DR7 LENn field.
-
-  @param  Length  Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
-
-  @retval Length  Appropriate converted values which DR7 LENn field accepts.
-
-**/
-UINTN
-ConvertLengthData (
-  IN     UINTN   Length
-  )
-{
-  if (Length == 1) {         //1-Byte length 
-    return 0;
-  } else if (Length == 2) {  //2-Byte length
-    return 1;
-  } else if (Length == 4) {  //4-Byte length
-    return 3;
-  } else {                   //Undefined or 8-byte length
-    return 2;
-  }
-}
-
-
-/**
-  Finds the next free debug register. If all the registers are occupied then 
-  EFI_OUT_OF_RESOURCES is returned.  
-
-  @param  SystemContext   Register content at time of the exception
-  @param  Register        Register value (0 - 3 for the first free debug register)
-
-  @retval EFI_STATUS      Appropriate status value.
-
-**/
-EFI_STATUS
-FindNextFreeDebugRegister (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  OUT UINTN               *Register
-  )
-{
-  IA32_DR7 Dr7;
-
-  Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
-  if (Dr7.Bits.G0 == 0) {
-    *Register = 0;
-  } else if (Dr7.Bits.G1 == 0) {
-    *Register = 1;
-  } else if (Dr7.Bits.G2 == 0) {
-    *Register = 2;
-  } else if (Dr7.Bits.G3 == 0) {
-    *Register = 3;
-  } else {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  return EFI_SUCCESS;
-}
-
-
-/**
-  Enables the debug register. Writes Address value to appropriate DR0-3 register.
-  Sets LENn, Gn, RWn bits in DR7 register.
-  @param  SystemContext   Register content at time of the exception
-  @param  Register        Register value (0 - 3) 
-  @param  Address         Breakpoint address value
-  @param  Type            Breakpoint type (Instruction, Data write, Data read 
-                          or write etc.)
-
-  @retval EFI_STATUS      Appropriate status value.
-
-**/
-EFI_STATUS
-EnableDebugRegister (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  UINTN               Register,
-  IN  UINTN               Address,
-  IN  UINTN               Length,
-  IN  UINTN               Type
-  )
-{
-  IA32_DR7  Dr7;
-
-  //Convert length data
-  Length = ConvertLengthData (Length);
-
-  //For Instruction execution, length should be 0 
-  //(Ref. Intel reference manual 18.2.4)
-  if ((Type == 0) && (Length != 0)) {
-    return EFI_INVALID_PARAMETER;
-  }
-  //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
-  //software breakpoint. We should send empty packet in both these cases.
-  if ((Type == (BREAK_TYPE)DataRead) || 
-      (Type == (BREAK_TYPE)SoftwareBreakpoint)) {
-    return EFI_UNSUPPORTED;
-  }
-
-  //Read DR7 so appropriate Gn, RWn and LENn bits can be modified.
-  Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
-  if (Register == 0) {
-    SystemContext.SystemContextIa32->Dr0 = Address;
-    Dr7.Bits.G0 = 1;
-    Dr7.Bits.RW0 = Type;
-    Dr7.Bits.LEN0 = Length;
-  } else if (Register == 1) {
-    SystemContext.SystemContextIa32->Dr1 = Address;
-    Dr7.Bits.G1 = 1;
-    Dr7.Bits.RW1 = Type;
-    Dr7.Bits.LEN1 = Length;
-  } else if (Register == 2) {
-    SystemContext.SystemContextIa32->Dr2 = Address;
-    Dr7.Bits.G2 = 1;
-    Dr7.Bits.RW2 = Type;
-    Dr7.Bits.LEN2 = Length;
-  } else if (Register == 3) {
-    SystemContext.SystemContextIa32->Dr3 = Address;
-    Dr7.Bits.G3 = 1;
-    Dr7.Bits.RW3 = Type;
-    Dr7.Bits.LEN3 = Length;
-  } else {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //Update Dr7 with appropriate Gn, RWn and LENn bits 
-  SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;
-
-  return EFI_SUCCESS;
-}
-
-
-/**
-  Returns register number 0 - 3 for the maching debug register.
-  This function compares incoming Address, Type, Length and
-  if there is a match then it returns the appropriate register number.
-  In case of mismatch, function returns EFI_NOT_FOUND message.
-
-  @param  SystemContext  Register content at time of the exception
-  @param  Address        Breakpoint address value
-  @param  Length         Breakpoint length value
-  @param  Type           Breakpoint type (Instruction, Data write, 
-                         Data read or write etc.)
-  @param  Register       Register value to be returned
-
-  @retval EFI_STATUS     Appropriate status value.
-
-**/
-EFI_STATUS
-FindMatchingDebugRegister (
- IN  EFI_SYSTEM_CONTEXT  SystemContext,
- IN  UINTN               Address,
- IN  UINTN               Length,
- IN  UINTN               Type,
- OUT UINTN               *Register
- )
-{
-  IA32_DR7 Dr7;
-
-  //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
-  //software breakpoint. We should send empty packet in both these cases.
-  if ((Type == (BREAK_TYPE)DataRead) || 
-      (Type == (BREAK_TYPE)SoftwareBreakpoint)) {
-    return EFI_UNSUPPORTED;
-  }
-
-  //Convert length data
-  Length = ConvertLengthData(Length);
-
-  Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
-  if ((Dr7.Bits.G0 == 1) && 
-      (Dr7.Bits.LEN0 == Length) &&
-      (Dr7.Bits.RW0 == Type) && 
-      (Address == SystemContext.SystemContextIa32->Dr0)) {
-    *Register = 0;
-  } else if ((Dr7.Bits.G1 == 1) && 
-             (Dr7.Bits.LEN1 == Length) &&
-             (Dr7.Bits.RW1 == Type) && 
-             (Address == SystemContext.SystemContextIa32->Dr1)) {
-    *Register = 1;
-  } else if ((Dr7.Bits.G2 == 1) && 
-             (Dr7.Bits.LEN2 == Length) &&
-             (Dr7.Bits.RW2 == Type) && 
-             (Address == SystemContext.SystemContextIa32->Dr2)) {
-    *Register = 2;
-  } else if ((Dr7.Bits.G3 == 1) && 
-             (Dr7.Bits.LEN3 == Length) &&
-             (Dr7.Bits.RW3 == Type) && 
-             (Address == SystemContext.SystemContextIa32->Dr3)) {
-    *Register = 3;
-  } else {
-    Print ((CHAR16 *)L"No match found..\n");
-    return EFI_NOT_FOUND;
-  }
-
-  return EFI_SUCCESS;
-}
-
-
-/**
-  Disables the particular debug register.
-
-  @param  SystemContext   Register content at time of the exception
-  @param  Register        Register to be disabled
-
-  @retval EFI_STATUS      Appropriate status value.
-
-**/
-EFI_STATUS
-DisableDebugRegister (
- IN  EFI_SYSTEM_CONTEXT  SystemContext,
- IN  UINTN               Register  
- )
-{
-  IA32_DR7  Dr7;
-  UINTN Address = 0;
-  //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
-  Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
-  if (Register == 0) {
-    SystemContext.SystemContextIa32->Dr0 = Address;
-    Dr7.Bits.G0 = 0;
-    Dr7.Bits.RW0 = 0;
-    Dr7.Bits.LEN0 = 0;
-  } else if (Register == 1) {
-    SystemContext.SystemContextIa32->Dr1 = Address;
-    Dr7.Bits.G1 = 0;
-    Dr7.Bits.RW1 = 0;
-    Dr7.Bits.LEN1 = 0;
-  } else if (Register == 2) {
-    SystemContext.SystemContextIa32->Dr2 = Address;
-    Dr7.Bits.G2 = 0;
-    Dr7.Bits.RW2 = 0;
-    Dr7.Bits.LEN2 = 0;
-  } else if (Register == 3) {
-    SystemContext.SystemContextIa32->Dr3 = Address;
-    Dr7.Bits.G3 = 0;
-    Dr7.Bits.RW3 = 0;
-    Dr7.Bits.LEN3 = 0;
-  } else {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
-  SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;
-
-  return EFI_SUCCESS;
-}
-
-
-/**
-  ‘Z1, [addr], [length]’
-  ‘Z2, [addr], [length]’
-  ‘Z3, [addr], [length]’
-  ‘Z4, [addr], [length]’
-
-  Insert hardware breakpoint/watchpoint at address addr of size length
-
-  @param SystemContext  Register content at time of the exception
-  @param *PacketData    Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-InsertBreakPoint (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  CHAR8              *PacketData
-  )
-{
-  UINTN Type;
-  UINTN Address;
-  UINTN Length;
-  UINTN Register;
-  EFI_STATUS Status;
-  BREAK_TYPE BreakType = NotSupported;
-  UINTN ErrorCode;
-
-  ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
-  if (ErrorCode > 0) {
-    SendError ((UINT8)ErrorCode);
-    return;
-  }
-
-  switch (Type) {
-
-    case    0:   //Software breakpoint
-      BreakType = SoftwareBreakpoint;
-      break;
-
-    case    1:   //Hardware breakpoint
-      BreakType = InstructionExecution;
-      break;
-
-    case    2:   //Write watchpoint
-      BreakType = DataWrite;
-      break;
-
-    case    3:   //Read watchpoint
-      BreakType = DataRead;
-      break;
-
-    case    4:   //Access watchpoint
-      BreakType = DataReadWrite;
-      break;
-
-    default  :
-      Print ((CHAR16 *)L"Insert breakpoint default: %x\n", Type);
-      SendError (GDB_EINVALIDBRKPOINTTYPE);
-      return;
-  }
-
-  // Find next free debug register
-  Status = FindNextFreeDebugRegister (SystemContext, &Register);
-  if (EFI_ERROR(Status)) {
-    Print ((CHAR16 *)L"No space left on device\n");
-    SendError (GDB_ENOSPACE);
-    return;
-  }
-
-  // Write Address, length data at particular DR register
-  Status = EnableDebugRegister (SystemContext, Register, Address, Length, (UINTN)BreakType);
-  if (EFI_ERROR(Status)) {
-    if (Status == EFI_UNSUPPORTED) {
-      SendNotSupported();
-      return;
-    }
-
-    SendError (GDB_EINVALIDARG);
-    return;
-  }
-
-  SendSuccess ();
-}
-
-
-/**
-  ‘z1, [addr], [length]’
-  ‘z2, [addr], [length]’
-  ‘z3, [addr], [length]’
-  ‘z4, [addr], [length]’
-
-  Remove hardware breakpoint/watchpoint at address addr of size length
-
-  @param *PacketData    Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-RemoveBreakPoint (
-  IN  EFI_SYSTEM_CONTEXT  SystemContext,
-  IN  CHAR8               *PacketData
-  )
-{
-  UINTN      Type;
-  UINTN      Address;
-  UINTN      Length;
-  UINTN      Register;
-  BREAK_TYPE BreakType = NotSupported;
-  EFI_STATUS Status;
-  UINTN      ErrorCode;
-
-  //Parse breakpoint packet data
-  ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
-  if (ErrorCode > 0) {
-    SendError ((UINT8)ErrorCode);
-    return;
-  }
-
-  switch (Type) {
-  
-    case    0:   //Software breakpoint
-      BreakType = SoftwareBreakpoint;
-      break;
-      
-    case    1:   //Hardware breakpoint
-      BreakType = InstructionExecution;
-      break;
-      
-    case    2:   //Write watchpoint
-      BreakType = DataWrite;
-      break;
-
-    case    3:   //Read watchpoint
-      BreakType = DataRead;
-      break;
-
-    case    4:   //Access watchpoint
-      BreakType = DataReadWrite;
-      break;
-
-    default  :
-      SendError (GDB_EINVALIDBRKPOINTTYPE);
-      return;
-  }
-
-  //Find matching debug register
-  Status = FindMatchingDebugRegister (SystemContext, Address, Length, (UINTN)BreakType, &Register);
-  if (EFI_ERROR(Status)) {
-    if (Status == EFI_UNSUPPORTED) {
-      SendNotSupported();
-      return;
-    }
-
-    SendError (GDB_ENOSPACE);
-    return;
-  }
-
-  //Remove breakpoint
-  Status = DisableDebugRegister(SystemContext, Register);
-  if (EFI_ERROR(Status)) {
-    SendError (GDB_EINVALIDARG);
-    return;
-  }
-
-  SendSuccess ();
-}
-
-
+}\r
+\r
+\r
+/**\r
+  Returns breakpoint data address from DR0-DR3 based on the input breakpoint number\r
+\r
+  @param  SystemContext      Register content at time of the exception\r
+  @param  BreakpointNumber   Breakpoint number\r
+\r
+  @retval Address            Data address from DR0-DR3 based on the breakpoint number.\r
+\r
+**/\r
+UINTN\r
+GetBreakpointDataAddress (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               BreakpointNumber\r
+  )\r
+{\r
+  UINTN Address;\r
+\r
+  if (BreakpointNumber == 1) {\r
+    Address = SystemContext.SystemContextIa32->Dr0;\r
+  } else if (BreakpointNumber == 2) {\r
+    Address = SystemContext.SystemContextIa32->Dr1;\r
+  } else if (BreakpointNumber == 3) {\r
+    Address = SystemContext.SystemContextIa32->Dr2;\r
+  } else if (BreakpointNumber == 4) {\r
+    Address = SystemContext.SystemContextIa32->Dr3;\r
+  } else {\r
+    Address = 0;\r
+  }\r
+\r
+  return Address;\r
+}\r
+\r
+\r
+/**\r
+  Returns currently detected breakpoint value based on the register DR6 B0-B3 field.\r
+  If no breakpoint is detected then it returns 0.\r
+\r
+  @param  SystemContext  Register content at time of the exception\r
+\r
+  @retval {1-4}          Currently detected breakpoint value   \r
+  @retval 0              No breakpoint detected.\r
\r
+**/\r
+UINTN\r
+GetBreakpointDetected (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext\r
+  )\r
+{\r
+  IA32_DR6 Dr6;\r
+  UINTN BreakpointNumber;\r
+\r
+  Dr6.UintN = SystemContext.SystemContextIa32->Dr6;\r
+\r
+  if (Dr6.Bits.B0 == 1) {\r
+    BreakpointNumber = 1;\r
+  } else if (Dr6.Bits.B1 == 1) {\r
+    BreakpointNumber = 2;\r
+  } else if (Dr6.Bits.B2 == 1) {\r
+    BreakpointNumber = 3;\r
+  } else if (Dr6.Bits.B3 == 1) {\r
+    BreakpointNumber = 4;\r
+  } else {\r
+    BreakpointNumber = 0;  //No breakpoint detected \r
+  }\r
+\r
+  return BreakpointNumber;\r
+}\r
+\r
+\r
+/**\r
+  Returns Breakpoint type (InstructionExecution, DataWrite, DataRead or DataReadWrite)\r
+  based on the Breakpoint number\r
+  \r
+  @param  SystemContext        Register content at time of the exception\r
+  @param  BreakpointNumber     Breakpoint number\r
+  \r
+  @retval BREAK_TYPE           Breakpoint type value read from register DR7 RWn field\r
+                               For unknown value, it returns NotSupported.\r
+  \r
+**/\r
+BREAK_TYPE\r
+GetBreakpointType (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               BreakpointNumber\r
+  )\r
+{\r
+  IA32_DR7 Dr7;\r
+  BREAK_TYPE Type = NotSupported;  //Default is NotSupported type\r
+\r
+  Dr7.UintN = SystemContext.SystemContextIa32->Dr7;\r
+\r
+  if (BreakpointNumber == 1) {\r
+    Type = (BREAK_TYPE) Dr7.Bits.RW0;  \r
+  } else if (BreakpointNumber == 2) {\r
+    Type = (BREAK_TYPE) Dr7.Bits.RW1;  \r
+  } else if (BreakpointNumber == 3) {\r
+    Type = (BREAK_TYPE) Dr7.Bits.RW2;  \r
+  } else if (BreakpointNumber == 4) {\r
+    Type = (BREAK_TYPE) Dr7.Bits.RW3;  \r
+  }\r
+\r
+  return Type;\r
+}\r
+\r
+\r
+/** \r
+  Parses Length and returns the length which DR7 LENn field accepts.\r
+  For example: If we receive 1-Byte length then we should return 0. \r
+               Zero gets written to DR7 LENn field.\r
+\r
+  @param  Length  Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)\r
+\r
+  @retval Length  Appropriate converted values which DR7 LENn field accepts.\r
+\r
+**/\r
+UINTN\r
+ConvertLengthData (\r
+  IN     UINTN   Length\r
+  )\r
+{\r
+  if (Length == 1) {         //1-Byte length \r
+    return 0;\r
+  } else if (Length == 2) {  //2-Byte length\r
+    return 1;\r
+  } else if (Length == 4) {  //4-Byte length\r
+    return 3;\r
+  } else {                   //Undefined or 8-byte length\r
+    return 2;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Finds the next free debug register. If all the registers are occupied then \r
+  EFI_OUT_OF_RESOURCES is returned.  \r
+\r
+  @param  SystemContext   Register content at time of the exception\r
+  @param  Register        Register value (0 - 3 for the first free debug register)\r
+\r
+  @retval EFI_STATUS      Appropriate status value.\r
+\r
+**/\r
+EFI_STATUS\r
+FindNextFreeDebugRegister (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  OUT UINTN               *Register\r
+  )\r
+{\r
+  IA32_DR7 Dr7;\r
+\r
+  Dr7.UintN = SystemContext.SystemContextIa32->Dr7;\r
+\r
+  if (Dr7.Bits.G0 == 0) {\r
+    *Register = 0;\r
+  } else if (Dr7.Bits.G1 == 0) {\r
+    *Register = 1;\r
+  } else if (Dr7.Bits.G2 == 0) {\r
+    *Register = 2;\r
+  } else if (Dr7.Bits.G3 == 0) {\r
+    *Register = 3;\r
+  } else {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Enables the debug register. Writes Address value to appropriate DR0-3 register.\r
+  Sets LENn, Gn, RWn bits in DR7 register.\r
\r
+  @param  SystemContext   Register content at time of the exception\r
+  @param  Register        Register value (0 - 3) \r
+  @param  Address         Breakpoint address value\r
+  @param  Type            Breakpoint type (Instruction, Data write, Data read \r
+                          or write etc.)\r
+\r
+  @retval EFI_STATUS      Appropriate status value.\r
+\r
+**/\r
+EFI_STATUS\r
+EnableDebugRegister (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  UINTN               Register,\r
+  IN  UINTN               Address,\r
+  IN  UINTN               Length,\r
+  IN  UINTN               Type\r
+  )\r
+{\r
+  IA32_DR7  Dr7;\r
+\r
+  //Convert length data\r
+  Length = ConvertLengthData (Length);\r
+\r
+  //For Instruction execution, length should be 0 \r
+  //(Ref. Intel reference manual 18.2.4)\r
+  if ((Type == 0) && (Length != 0)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
\r
+  //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle\r
+  //software breakpoint. We should send empty packet in both these cases.\r
+  if ((Type == (BREAK_TYPE)DataRead) || \r
+      (Type == (BREAK_TYPE)SoftwareBreakpoint)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //Read DR7 so appropriate Gn, RWn and LENn bits can be modified.\r
+  Dr7.UintN = SystemContext.SystemContextIa32->Dr7;\r
+\r
+  if (Register == 0) {\r
+    SystemContext.SystemContextIa32->Dr0 = Address;\r
+    Dr7.Bits.G0 = 1;\r
+    Dr7.Bits.RW0 = Type;\r
+    Dr7.Bits.LEN0 = Length;\r
+  } else if (Register == 1) {\r
+    SystemContext.SystemContextIa32->Dr1 = Address;\r
+    Dr7.Bits.G1 = 1;\r
+    Dr7.Bits.RW1 = Type;\r
+    Dr7.Bits.LEN1 = Length;\r
+  } else if (Register == 2) {\r
+    SystemContext.SystemContextIa32->Dr2 = Address;\r
+    Dr7.Bits.G2 = 1;\r
+    Dr7.Bits.RW2 = Type;\r
+    Dr7.Bits.LEN2 = Length;\r
+  } else if (Register == 3) {\r
+    SystemContext.SystemContextIa32->Dr3 = Address;\r
+    Dr7.Bits.G3 = 1;\r
+    Dr7.Bits.RW3 = Type;\r
+    Dr7.Bits.LEN3 = Length;\r
+  } else {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //Update Dr7 with appropriate Gn, RWn and LENn bits \r
+  SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Returns register number 0 - 3 for the maching debug register.\r
+  This function compares incoming Address, Type, Length and\r
+  if there is a match then it returns the appropriate register number.\r
+  In case of mismatch, function returns EFI_NOT_FOUND message.\r
+\r
+  @param  SystemContext  Register content at time of the exception\r
+  @param  Address        Breakpoint address value\r
+  @param  Length         Breakpoint length value\r
+  @param  Type           Breakpoint type (Instruction, Data write, \r
+                         Data read or write etc.)\r
+  @param  Register       Register value to be returned\r
+\r
+  @retval EFI_STATUS     Appropriate status value.\r
+\r
+**/\r
+EFI_STATUS\r
+FindMatchingDebugRegister (\r
+ IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+ IN  UINTN               Address,\r
+ IN  UINTN               Length,\r
+ IN  UINTN               Type,\r
+ OUT UINTN               *Register\r
+ )\r
+{\r
+  IA32_DR7 Dr7;\r
+\r
+  //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle\r
+  //software breakpoint. We should send empty packet in both these cases.\r
+  if ((Type == (BREAK_TYPE)DataRead) || \r
+      (Type == (BREAK_TYPE)SoftwareBreakpoint)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //Convert length data\r
+  Length = ConvertLengthData(Length);\r
+\r
+  Dr7.UintN = SystemContext.SystemContextIa32->Dr7;\r
+\r
+  if ((Dr7.Bits.G0 == 1) && \r
+      (Dr7.Bits.LEN0 == Length) &&\r
+      (Dr7.Bits.RW0 == Type) && \r
+      (Address == SystemContext.SystemContextIa32->Dr0)) {\r
+    *Register = 0;\r
+  } else if ((Dr7.Bits.G1 == 1) && \r
+             (Dr7.Bits.LEN1 == Length) &&\r
+             (Dr7.Bits.RW1 == Type) && \r
+             (Address == SystemContext.SystemContextIa32->Dr1)) {\r
+    *Register = 1;\r
+  } else if ((Dr7.Bits.G2 == 1) && \r
+             (Dr7.Bits.LEN2 == Length) &&\r
+             (Dr7.Bits.RW2 == Type) && \r
+             (Address == SystemContext.SystemContextIa32->Dr2)) {\r
+    *Register = 2;\r
+  } else if ((Dr7.Bits.G3 == 1) && \r
+             (Dr7.Bits.LEN3 == Length) &&\r
+             (Dr7.Bits.RW3 == Type) && \r
+             (Address == SystemContext.SystemContextIa32->Dr3)) {\r
+    *Register = 3;\r
+  } else {\r
+    Print ((CHAR16 *)L"No match found..\n");\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Disables the particular debug register.\r
+\r
+  @param  SystemContext   Register content at time of the exception\r
+  @param  Register        Register to be disabled\r
+\r
+  @retval EFI_STATUS      Appropriate status value.\r
+\r
+**/\r
+EFI_STATUS\r
+DisableDebugRegister (\r
+ IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+ IN  UINTN               Register  \r
+ )\r
+{\r
+  IA32_DR7  Dr7;\r
+  UINTN Address = 0;\r
\r
+  //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off.\r
+  Dr7.UintN = SystemContext.SystemContextIa32->Dr7;\r
+\r
+  if (Register == 0) {\r
+    SystemContext.SystemContextIa32->Dr0 = Address;\r
+    Dr7.Bits.G0 = 0;\r
+    Dr7.Bits.RW0 = 0;\r
+    Dr7.Bits.LEN0 = 0;\r
+  } else if (Register == 1) {\r
+    SystemContext.SystemContextIa32->Dr1 = Address;\r
+    Dr7.Bits.G1 = 0;\r
+    Dr7.Bits.RW1 = 0;\r
+    Dr7.Bits.LEN1 = 0;\r
+  } else if (Register == 2) {\r
+    SystemContext.SystemContextIa32->Dr2 = Address;\r
+    Dr7.Bits.G2 = 0;\r
+    Dr7.Bits.RW2 = 0;\r
+    Dr7.Bits.LEN2 = 0;\r
+  } else if (Register == 3) {\r
+    SystemContext.SystemContextIa32->Dr3 = Address;\r
+    Dr7.Bits.G3 = 0;\r
+    Dr7.Bits.RW3 = 0;\r
+    Dr7.Bits.LEN3 = 0;\r
+  } else {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off.\r
+  SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  ‘Z1, [addr], [length]’\r
+  ‘Z2, [addr], [length]’\r
+  ‘Z3, [addr], [length]’\r
+  ‘Z4, [addr], [length]’\r
+\r
+  Insert hardware breakpoint/watchpoint at address addr of size length\r
+\r
+  @param SystemContext  Register content at time of the exception\r
+  @param *PacketData    Pointer to the Payload data for the packet\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InsertBreakPoint (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  CHAR8              *PacketData\r
+  )\r
+{\r
+  UINTN Type;\r
+  UINTN Address;\r
+  UINTN Length;\r
+  UINTN Register;\r
+  EFI_STATUS Status;\r
+  BREAK_TYPE BreakType = NotSupported;\r
+  UINTN ErrorCode;\r
+\r
+  ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);\r
+  if (ErrorCode > 0) {\r
+    SendError ((UINT8)ErrorCode);\r
+    return;\r
+  }\r
+\r
+  switch (Type) {\r
+\r
+    case    0:   //Software breakpoint\r
+      BreakType = SoftwareBreakpoint;\r
+      break;\r
+\r
+    case    1:   //Hardware breakpoint\r
+      BreakType = InstructionExecution;\r
+      break;\r
+\r
+    case    2:   //Write watchpoint\r
+      BreakType = DataWrite;\r
+      break;\r
+\r
+    case    3:   //Read watchpoint\r
+      BreakType = DataRead;\r
+      break;\r
+\r
+    case    4:   //Access watchpoint\r
+      BreakType = DataReadWrite;\r
+      break;\r
+\r
+    default  :\r
+      Print ((CHAR16 *)L"Insert breakpoint default: %x\n", Type);\r
+      SendError (GDB_EINVALIDBRKPOINTTYPE);\r
+      return;\r
+  }\r
+\r
+  // Find next free debug register\r
+  Status = FindNextFreeDebugRegister (SystemContext, &Register);\r
+  if (EFI_ERROR(Status)) {\r
+    Print ((CHAR16 *)L"No space left on device\n");\r
+    SendError (GDB_ENOSPACE);\r
+    return;\r
+  }\r
+\r
+  // Write Address, length data at particular DR register\r
+  Status = EnableDebugRegister (SystemContext, Register, Address, Length, (UINTN)BreakType);\r
+  if (EFI_ERROR(Status)) {\r
+    if (Status == EFI_UNSUPPORTED) {\r
+      SendNotSupported();\r
+      return;\r
+    }\r
+\r
+    SendError (GDB_EINVALIDARG);\r
+    return;\r
+  }\r
+\r
+  SendSuccess ();\r
+}\r
+\r
+\r
+/**\r
+  ‘z1, [addr], [length]’\r
+  ‘z2, [addr], [length]’\r
+  ‘z3, [addr], [length]’\r
+  ‘z4, [addr], [length]’\r
+\r
+  Remove hardware breakpoint/watchpoint at address addr of size length\r
+\r
+  @param *PacketData    Pointer to the Payload data for the packet\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+RemoveBreakPoint (\r
+  IN  EFI_SYSTEM_CONTEXT  SystemContext,\r
+  IN  CHAR8               *PacketData\r
+  )\r
+{\r
+  UINTN      Type;\r
+  UINTN      Address;\r
+  UINTN      Length;\r
+  UINTN      Register;\r
+  BREAK_TYPE BreakType = NotSupported;\r
+  EFI_STATUS Status;\r
+  UINTN      ErrorCode;\r
+\r
+  //Parse breakpoint packet data\r
+  ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);\r
+  if (ErrorCode > 0) {\r
+    SendError ((UINT8)ErrorCode);\r
+    return;\r
+  }\r
+\r
+  switch (Type) {\r
+  \r
+    case    0:   //Software breakpoint\r
+      BreakType = SoftwareBreakpoint;\r
+      break;\r
+      \r
+    case    1:   //Hardware breakpoint\r
+      BreakType = InstructionExecution;\r
+      break;\r
+      \r
+    case    2:   //Write watchpoint\r
+      BreakType = DataWrite;\r
+      break;\r
+\r
+    case    3:   //Read watchpoint\r
+      BreakType = DataRead;\r
+      break;\r
+\r
+    case    4:   //Access watchpoint\r
+      BreakType = DataReadWrite;\r
+      break;\r
+\r
+    default  :\r
+      SendError (GDB_EINVALIDBRKPOINTTYPE);\r
+      return;\r
+  }\r
+\r
+  //Find matching debug register\r
+  Status = FindMatchingDebugRegister (SystemContext, Address, Length, (UINTN)BreakType, &Register);\r
+  if (EFI_ERROR(Status)) {\r
+    if (Status == EFI_UNSUPPORTED) {\r
+      SendNotSupported();\r
+      return;\r
+    }\r
+\r
+    SendError (GDB_ENOSPACE);\r
+    return;\r
+  }\r
+\r
+  //Remove breakpoint\r
+  Status = DisableDebugRegister(SystemContext, Register);\r
+  if (EFI_ERROR(Status)) {\r
+    SendError (GDB_EINVALIDARG);\r
+    return;\r
+  }\r
+\r
+  SendSuccess ();\r
+}\r
+\r
+\r
 /**\r
   Initialize debug agent.\r
 \r