/** @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.

**/

#include <GdbStubInternal.h>

//
// 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);
}


/**
 Return the number of entries in the gRegisters[]

 @retval  UINTN, the number of entries (registers) in the gRegisters[] array.
 **/
UINTN
MaxRegisterCount (
  VOID
  )
{
  return sizeof (gRegisterOffsets)/sizeof (UINTN);
}


/**
  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 >= MaxRegisterCount())) {
    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 < MaxRegisterCount() ; 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 >= MaxRegisterCount())) {
    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 < MaxRegisterCount(); i++) {  // there are only 16 registers to write
    InBufPtr = BasicWriteRegister (SystemContext, i, InBufPtr);
  }

  SendSuccess();
}


/**
 Insert Single Step in the SystemContext

 @param SystemContext Register content at time of the exception
 **/
VOID
AddSingleStep (
  IN  EFI_SYSTEM_CONTEXT  SystemContext
  )
{
  SystemContext.SystemContextIa32->Eflags |= TF_BIT; //Setting the TF bit.
}


/**
 Remove Single Step in the SystemContext

 @param SystemContext Register content at time of the exception
 **/
VOID
RemoveSingleStep (
  IN  EFI_SYSTEM_CONTEXT  SystemContext
  )
{
  SystemContext.SystemContextIa32->Eflags &= ~TF_BIT;  // clearing the TF bit.
}



/** ‘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
  )
{
  if (PacketData[1] != '\0') {
    SystemContext.SystemContextIa32->Eip = AsciiStrHexToUintn (&PacketData[1]);
  }

  AddSingleStep (SystemContext);
}


/**
  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) {
      Print ((CHAR16 *)L"Not supported\n");
      SendNotSupported ();
      return;
    }

    Print ((CHAR16 *)L"Invalid argument\n");
    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) {
      Print ((CHAR16 *)L"Not supported.\n");
      SendNotSupported ();
      return;
    }

    Print ((CHAR16 *)L"No matching register found.\n");
    SendError (GDB_ENOSPACE);
    return;
  }

  //Remove breakpoint
  Status = DisableDebugRegister (SystemContext, Register);
  if (EFI_ERROR(Status)) {
    Print ((CHAR16 *)L"Invalid argument.\n");
    SendError (GDB_EINVALIDARG);
    return;
  }

  SendSuccess ();
}


VOID
InitializeProcessor (
  VOID
  )
{
}

BOOLEAN
ValidateAddress (
  IN  VOID  *Address
  )
{
  return TRUE;
}

BOOLEAN
ValidateException (
  IN  EFI_EXCEPTION_TYPE    ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT SystemContext
  )
{
  return TRUE;
}

