/** @file
  Processor specific parts of the GDB stub

  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <GdbStubInternal.h>

//
// Array of exception types that need to be hooked by the debugger
//
EFI_EXCEPTION_TYPE_ENTRY  gExceptionType[] = {
  { EXCEPT_X64_DIVIDE_ERROR,    GDB_SIGFPE  },
  { EXCEPT_X64_DEBUG,           GDB_SIGTRAP },
  { EXCEPT_X64_NMI,             GDB_SIGEMT  },
  { EXCEPT_X64_BREAKPOINT,      GDB_SIGTRAP },
  { EXCEPT_X64_OVERFLOW,        GDB_SIGSEGV },
  { EXCEPT_X64_BOUND,           GDB_SIGSEGV },
  { EXCEPT_X64_INVALID_OPCODE,  GDB_SIGILL  },
  { EXCEPT_X64_DOUBLE_FAULT,    GDB_SIGEMT  },
  { EXCEPT_X64_STACK_FAULT,     GDB_SIGSEGV },
  { EXCEPT_X64_GP_FAULT,        GDB_SIGSEGV },
  { EXCEPT_X64_PAGE_FAULT,      GDB_SIGSEGV },
  { EXCEPT_X64_FP_ERROR,        GDB_SIGEMT  },
  { EXCEPT_X64_ALIGNMENT_CHECK, GDB_SIGEMT  },
  { EXCEPT_X64_MACHINE_CHECK,   GDB_SIGEMT  }
};

// The offsets of registers SystemContextX64.
// The fields in the array are in the gdb ordering.
// HAVE TO DOUBLE-CHECK THE ORDER of the 24 regs
//
UINTN  gRegisterOffsets[] = {
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Rax),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Rcx),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Rdx),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Rbx),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Rsp),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Rbp),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Rsi),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Rdi),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Rip),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Rflags),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Cs),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Ss),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Ds),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Es),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Fs),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, Gs),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, R8),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, R9),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, R10),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, R11),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, R12),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, R13),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, R14),
  OFFSET_OF (EFI_SYSTEM_CONTEXT_X64, R15)
};

/**
 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
**/
BOOLEAN
CheckIsa (
  IN  EFI_INSTRUCTION_SET_ARCHITECTURE  Isa
  )
{
  return (BOOLEAN)(Isa == IsaX64);
}

/**
 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 X64 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.SystemContextX64) + 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 < 64) {
    *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
ReadNthRegister (
  IN  EFI_SYSTEM_CONTEXT  SystemContext,
  IN  CHAR8               *InBuffer
  )
{
  UINTN  RegNumber;
  CHAR8  OutBuffer[17]; // 1 reg=16 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[385]; // 24 regs, 16 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 24 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
  UINT64  NewValue;  // the new value of the RegNumber-th Register

  NewValue = 0;
  RegSize  = 0;
  while (RegSize < 64) {
    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      Pointer 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) = 385
  if (AsciiStrLen (InBuffer) != 385) {
    // 24 regs, 16 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.SystemContextX64->Rflags |= 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.SystemContextX64->Rflags &= ~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.SystemContextX64->Rip = 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.SystemContextX64->Rip = 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 matching 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;
}
