/** @file
  Common Debug Agent library implementation. It mainly includes
  the first C function called by exception/interrupt handlers,
  read/write debug packet to communication with HOST based on transfer
  protocol.

  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DebugAgent.h"
#include "Ia32/DebugException.h"

GLOBAL_REMOVE_IF_UNREFERENCED CHAR8  mErrorMsgVersionAlert[]       = "\rThe SourceLevelDebugPkg you are using requires a newer version of the Intel(R) UDK Debugger Tool.\r\n";
GLOBAL_REMOVE_IF_UNREFERENCED CHAR8  mErrorMsgSendInitPacket[]     = "\rSend INIT break packet and try to connect the HOST (Intel(R) UDK Debugger Tool v1.5) ...\r\n";
GLOBAL_REMOVE_IF_UNREFERENCED CHAR8  mErrorMsgConnectOK[]          = "HOST connection is successful!\r\n";
GLOBAL_REMOVE_IF_UNREFERENCED CHAR8  mErrorMsgConnectFail[]        = "HOST connection is failed!\r\n";
GLOBAL_REMOVE_IF_UNREFERENCED CHAR8  mWarningMsgIngoreBreakpoint[] = "Ignore break point in SMM for SMI issued during DXE debugging!\r\n";

//
// Vector Handoff Info list used by Debug Agent for persist
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_VECTOR_HANDOFF_INFO  mVectorHandoffInfoDebugAgent[] = {
  {
    DEBUG_EXCEPT_DIVIDE_ERROR,         // Vector 0
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_DEBUG,                // Vector 1
    EFI_VECTOR_HANDOFF_DO_NOT_HOOK,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_NMI,                  // Vector 2
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_BREAKPOINT,           // Vector 3
    EFI_VECTOR_HANDOFF_DO_NOT_HOOK,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_OVERFLOW,             // Vector 4
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_BOUND,                // Vector 5
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_INVALID_OPCODE,       // Vector 6
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_DOUBLE_FAULT,         // Vector 8
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_INVALID_TSS,          // Vector 10
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_SEG_NOT_PRESENT,      // Vector 11
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_STACK_FAULT,          // Vector 12
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_GP_FAULT,             // Vector 13
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_PAGE_FAULT,           // Vector 14
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_FP_ERROR,             // Vector 16
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_ALIGNMENT_CHECK,      // Vector 17
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_MACHINE_CHECK,        // Vector 18
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_EXCEPT_SIMD,                 // Vector 19
    EFI_VECTOR_HANDOFF_HOOK_BEFORE,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_TIMER_VECTOR,                // Vector 32
    EFI_VECTOR_HANDOFF_DO_NOT_HOOK,
    EFI_DEBUG_AGENT_GUID
  },
  {
    DEBUG_MAILBOX_VECTOR,              // Vector 33
    EFI_VECTOR_HANDOFF_DO_NOT_HOOK,
    EFI_DEBUG_AGENT_GUID
  },
  {
    0,
    EFI_VECTOR_HANDOFF_LAST_ENTRY,
    { 0 }
  }
};

GLOBAL_REMOVE_IF_UNREFERENCED UINTN  mVectorHandoffInfoCount = sizeof (mVectorHandoffInfoDebugAgent) / sizeof (EFI_VECTOR_HANDOFF_INFO);

/**
  Calculate CRC16 for target data.

  @param[in]  Data              The target data.
  @param[in]  DataSize          The target data size.
  @param[in]  Crc               Initial CRC.

  @return UINT16     The CRC16 value.

**/
UINT16
CalculateCrc16 (
  IN UINT8   *Data,
  IN UINTN   DataSize,
  IN UINT16  Crc
  )
{
  UINTN  Index;
  UINTN  BitIndex;

  for (Index = 0; Index < DataSize; Index++) {
    Crc ^= (UINT16)Data[Index];
    for (BitIndex = 0; BitIndex < 8; BitIndex++) {
      if ((Crc & 0x8000) != 0) {
        Crc <<= 1;
        Crc  ^= 0x1021;
      } else {
        Crc <<= 1;
      }
    }
  }

  return Crc;
}

/**
  Read IDT entry to check if IDT entries are setup by Debug Agent.

  @retval  TRUE     IDT entries were setup by Debug Agent.
  @retval  FALSE    IDT entries were not setup by Debug Agent.

**/
BOOLEAN
IsDebugAgentInitialzed (
  VOID
  )
{
  UINTN  InterruptHandler;

  InterruptHandler = (UINTN)GetExceptionHandlerInIdtEntry (0);
  if ((InterruptHandler >= 4) &&  (*(UINT32 *)(InterruptHandler - 4) == AGENT_HANDLER_SIGNATURE)) {
    return TRUE;
  } else {
    return FALSE;
  }
}

/**
  Find and report module image info to HOST.

  @param[in] AlignSize      Image aligned size.

**/
VOID
FindAndReportModuleImageInfo (
  IN UINTN  AlignSize
  )
{
  UINTN                         Pe32Data;
  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;

  //
  // Find Image Base
  //
  Pe32Data = PeCoffSearchImageBase ((UINTN)mErrorMsgVersionAlert);
  if (Pe32Data != 0) {
    ImageContext.ImageAddress = Pe32Data;
    ImageContext.PdbPointer   = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
    PeCoffLoaderRelocateImageExtraAction (&ImageContext);
  }
}

/**
  Trigger one software interrupt to debug agent to handle it.

  @param[in] Signature       Software interrupt signature.

**/
VOID
TriggerSoftInterrupt (
  IN UINT32  Signature
  )
{
  UINTN  Dr0;
  UINTN  Dr1;

  //
  // Save Debug Register State
  //
  Dr0 = AsmReadDr0 ();
  Dr1 = AsmReadDr1 ();

  //
  // DR0 = Signature
  //
  AsmWriteDr0 (SOFT_INTERRUPT_SIGNATURE);
  AsmWriteDr1 (Signature);

  //
  // Do INT3 to communicate with HOST side
  //
  CpuBreakpoint ();

  //
  // Restore Debug Register State only when Host didn't change it inside exception handler.
  //   Dr registers can only be changed by setting the HW breakpoint.
  //
  AsmWriteDr0 (Dr0);
  AsmWriteDr1 (Dr1);
}

/**
  Calculate Mailbox checksum and update the checksum field.

  @param[in]  Mailbox  Debug Agent Mailbox pointer.

**/
VOID
UpdateMailboxChecksum (
  IN DEBUG_AGENT_MAILBOX  *Mailbox
  )
{
  Mailbox->CheckSum = CalculateCheckSum8 ((UINT8 *)Mailbox, sizeof (DEBUG_AGENT_MAILBOX) - 2);
}

/**
  Verify Mailbox checksum.

  If checksum error, print debug message and run init dead loop.

  @param[in]  Mailbox  Debug Agent Mailbox pointer.

**/
VOID
VerifyMailboxChecksum (
  IN DEBUG_AGENT_MAILBOX  *Mailbox
  )
{
  UINT8  CheckSum;

  CheckSum = CalculateCheckSum8 ((UINT8 *)Mailbox, sizeof (DEBUG_AGENT_MAILBOX) - 2);
  //
  // The checksum updating process may be disturbed by hardware SMI, we need to check CheckSum field
  // and ToBeCheckSum field to validate the mail box.
  //
  if ((CheckSum != Mailbox->CheckSum) && (CheckSum != Mailbox->ToBeCheckSum)) {
    DEBUG ((DEBUG_ERROR, "DebugAgent: Mailbox checksum error, stack or heap crashed!\n"));
    DEBUG ((DEBUG_ERROR, "DebugAgent: CheckSum = %x, Mailbox->CheckSum = %x, Mailbox->ToBeCheckSum = %x\n", CheckSum, Mailbox->CheckSum, Mailbox->ToBeCheckSum));
    CpuDeadLoop ();
  }
}

/**
  Update Mailbox content by index.

  @param[in]  Mailbox  Debug Agent Mailbox pointer.
  @param[in]  Index    Mailbox content index.
  @param[in]  Value    Value to be set into Mailbox.

**/
VOID
UpdateMailboxContent (
  IN DEBUG_AGENT_MAILBOX  *Mailbox,
  IN UINTN                Index,
  IN UINT64               Value
  )
{
  AcquireMpSpinLock (&mDebugMpContext.MailboxSpinLock);
  switch (Index) {
    case DEBUG_MAILBOX_DEBUG_FLAG_INDEX:
      Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugFlag.Uint64, sizeof (UINT64))
                              - CalculateSum8 ((UINT8 *)&Value, sizeof (UINT64));
      Mailbox->DebugFlag.Uint64 = Value;
      break;
    case DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX:
      Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugPortHandle, sizeof (UINTN))
                              - CalculateSum8 ((UINT8 *)&Value, sizeof (UINTN));
      Mailbox->DebugPortHandle = (UINTN)Value;
      break;
    case DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX:
      Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->ExceptionBufferPointer, sizeof (UINTN))
                              - CalculateSum8 ((UINT8 *)&Value, sizeof (UINTN));
      Mailbox->ExceptionBufferPointer = (UINTN)Value;
      break;
    case DEBUG_MAILBOX_LAST_ACK:
      Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->LastAck, sizeof (UINT8))
                              - CalculateSum8 ((UINT8 *)&Value, sizeof (UINT8));
      Mailbox->LastAck = (UINT8)Value;
      break;
    case DEBUG_MAILBOX_SEQUENCE_NO_INDEX:
      Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->SequenceNo, sizeof (UINT8))
                              - CalculateSum8 ((UINT8 *)&Value, sizeof (UINT8));
      Mailbox->SequenceNo = (UINT8)Value;
      break;
    case DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX:
      Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->HostSequenceNo, sizeof (UINT8))
                              - CalculateSum8 ((UINT8 *)&Value, sizeof (UINT8));
      Mailbox->HostSequenceNo = (UINT8)Value;
      break;
    case DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY:
      Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugTimerFrequency, sizeof (UINT32))
                              - CalculateSum8 ((UINT8 *)&Value, sizeof (UINT32));
      Mailbox->DebugTimerFrequency = (UINT32)Value;
      break;
  }

  UpdateMailboxChecksum (Mailbox);
  ReleaseMpSpinLock (&mDebugMpContext.MailboxSpinLock);
}

/**
  Read data from debug device and save the data in buffer.

  Reads NumberOfBytes data bytes from a debug device into the buffer
  specified by Buffer. The number of bytes actually read is returned.
  If the return value is less than NumberOfBytes, then the rest operation failed.
  If NumberOfBytes is zero, then return 0.

  @param  Handle           Debug port handle.
  @param  Buffer           Pointer to the data buffer to store the data read from the debug device.
  @param  NumberOfBytes    Number of bytes which will be read.
  @param  Timeout          Timeout value for reading from debug device. It unit is Microsecond.

  @retval 0                Read data failed, no data is to be read.
  @retval >0               Actual number of bytes read from debug device.

**/
UINTN
DebugAgentReadBuffer (
  IN DEBUG_PORT_HANDLE  Handle,
  IN UINT8              *Buffer,
  IN UINTN              NumberOfBytes,
  IN UINTN              Timeout
  )
{
  UINTN   Index;
  UINT32  Begin;
  UINT32  TimeoutTicker;
  UINT32  TimerRound;
  UINT32  TimerFrequency;
  UINT32  TimerCycle;

  Begin          = 0;
  TimeoutTicker  = 0;
  TimerRound     = 0;
  TimerFrequency = GetMailboxPointer ()->DebugTimerFrequency;
  TimerCycle     = GetApicTimerInitCount ();

  if (Timeout != 0) {
    Begin         = GetApicTimerCurrentCount ();
    TimeoutTicker = (UINT32)DivU64x32 (
                              MultU64x64 (
                                TimerFrequency,
                                Timeout
                                ),
                              1000000u
                              );
    TimerRound = (UINT32)DivU64x32Remainder (TimeoutTicker, TimerCycle / 2, &TimeoutTicker);
  }

  Index = 0;
  while (Index < NumberOfBytes) {
    if (DebugPortPollBuffer (Handle)) {
      DebugPortReadBuffer (Handle, Buffer + Index, 1, 0);
      Index++;
      continue;
    }

    if (Timeout != 0) {
      if (TimerRound == 0) {
        if (IsDebugTimerTimeout (TimerCycle, Begin, TimeoutTicker)) {
          //
          // If time out occurs.
          //
          return 0;
        }
      } else {
        if (IsDebugTimerTimeout (TimerCycle, Begin, TimerCycle / 2)) {
          TimerRound--;
          Begin = GetApicTimerCurrentCount ();
        }
      }
    }
  }

  return Index;
}

/**
  Set debug flag in mailbox.

  @param[in]  FlagMask      Debug flag mask value.
  @param[in]  FlagValue     Debug flag value.

**/
VOID
SetDebugFlag (
  IN UINT64  FlagMask,
  IN UINT32  FlagValue
  )
{
  DEBUG_AGENT_MAILBOX  *Mailbox;
  UINT64               Data64;

  Mailbox = GetMailboxPointer ();
  Data64  = (Mailbox->DebugFlag.Uint64 & ~FlagMask) |
            (LShiftU64 ((UINT64)FlagValue, LowBitSet64 (FlagMask)) & FlagMask);
  UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_FLAG_INDEX, Data64);
}

/**
  Get debug flag in mailbox.

  @param[in]  FlagMask      Debug flag mask value.

  @return Debug flag value.

**/
UINT32
GetDebugFlag (
  IN UINT64  FlagMask
  )
{
  DEBUG_AGENT_MAILBOX  *Mailbox;
  UINT32               DebugFlag;

  Mailbox   = GetMailboxPointer ();
  DebugFlag = (UINT32)RShiftU64 (Mailbox->DebugFlag.Uint64 & FlagMask, LowBitSet64 (FlagMask));

  return DebugFlag;
}

/**
  Send a debug message packet to the debug port.

  @param[in] Buffer  The debug message.
  @param[in] Length  The length of debug message.

**/
VOID
SendDebugMsgPacket (
  IN CHAR8  *Buffer,
  IN UINTN  Length
  )
{
  DEBUG_PACKET_HEADER  DebugHeader;
  DEBUG_PORT_HANDLE    Handle;

  Handle = GetDebugPortHandle ();

  DebugHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;
  DebugHeader.Command     = DEBUG_COMMAND_PRINT_MESSAGE;
  DebugHeader.Length      = sizeof (DEBUG_PACKET_HEADER) + (UINT8)Length;
  DebugHeader.SequenceNo  = 0xEE;
  DebugHeader.Crc         = 0;
  DebugHeader.Crc         = CalculateCrc16 (
                              (UINT8 *)Buffer,
                              Length,
                              CalculateCrc16 ((UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER), 0)
                              );

  DebugPortWriteBuffer (Handle, (UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER));
  DebugPortWriteBuffer (Handle, (UINT8 *)Buffer, Length);
}

/**
  Prints a debug message to the debug port if the specified error level is enabled.

  If any bit in ErrorLevel is also set in Mainbox, then print the message specified
  by Format and the associated variable argument list to the debug port.

  @param[in] ErrorLevel  The error level of the debug message.
  @param[in] Format      Format string for the debug message to print.
  @param[in] ...         Variable argument list whose contents are accessed
                         based on the format string specified by Format.

**/
VOID
EFIAPI
DebugAgentMsgPrint (
  IN UINT8  ErrorLevel,
  IN CHAR8  *Format,
  ...
  )
{
  CHAR8    Buffer[DEBUG_DATA_MAXIMUM_REAL_DATA];
  VA_LIST  Marker;

  //
  // Check driver debug mask value and global mask
  //
  if ((ErrorLevel & GetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL)) == 0) {
    return;
  }

  //
  // Convert the DEBUG() message to an ASCII String
  //
  VA_START (Marker, Format);
  AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
  VA_END (Marker);

  SendDebugMsgPacket (Buffer, AsciiStrLen (Buffer));
}

/**
  Prints a debug message to the debug output device if the specified error level is enabled.

  If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
  GetDebugPrintErrorLevel (), then print the message specified by Format and the
  associated variable argument list to the debug output device.

  If Format is NULL, then ASSERT().

  @param[in] ErrorLevel  The error level of the debug message.
  @param[in] IsSend      Flag of debug message to declare that the data is being sent or being received.
  @param[in] Data        Variable argument list whose contents are accessed
  @param[in] Length      based on the format string specified by Format.

**/
VOID
EFIAPI
DebugAgentDataMsgPrint (
  IN UINT8    ErrorLevel,
  IN BOOLEAN  IsSend,
  IN UINT8    *Data,
  IN UINT8    Length
  )
{
  CHAR8  Buffer[DEBUG_DATA_MAXIMUM_REAL_DATA];
  CHAR8  *DestBuffer;
  UINTN  Index;

  //
  // Check driver debug mask value and global mask
  //
  if ((ErrorLevel & GetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL)) == 0) {
    return;
  }

  DestBuffer = Buffer;
  if (IsSend) {
    DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA, "Sent data [ ");
  } else {
    DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA, "Received data [ ");
  }

  Index = 0;
  while (TRUE) {
    if (DestBuffer - Buffer > DEBUG_DATA_MAXIMUM_REAL_DATA - 6) {
      //
      // If there was no enough space in buffer, send out the debug message,
      // reserving 6 bytes is for the last data and end characters "]\n".
      //
      SendDebugMsgPacket (Buffer, DestBuffer - Buffer);
      DestBuffer = Buffer;
    }

    DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA - (DestBuffer - Buffer), "%02x ", Data[Index]);
    Index++;
    if (Index >= Length) {
      //
      // The last character of debug message has been formatted in buffer
      //
      DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA - (DestBuffer - Buffer), "]\n");
      SendDebugMsgPacket (Buffer, DestBuffer - Buffer);
      break;
    }
  }
}

/**
  Read remaining debug packet except for the start symbol

  @param[in]      Handle        Pointer to Debug Port handle.
  @param[in, out] DebugHeader   Debug header buffer including start symbol.

  @retval EFI_SUCCESS        Read the symbol in BreakSymbol.
  @retval EFI_CRC_ERROR      CRC check fail.
  @retval EFI_TIMEOUT        Timeout occurs when reading debug packet.
  @retval EFI_DEVICE_ERROR   Receive the old or response packet.

**/
EFI_STATUS
ReadRemainingBreakPacket (
  IN     DEBUG_PORT_HANDLE    Handle,
  IN OUT DEBUG_PACKET_HEADER  *DebugHeader
  )
{
  UINT16               Crc;
  DEBUG_AGENT_MAILBOX  *Mailbox;

  //
  // Has received start symbol, try to read the rest part
  //
  if (DebugAgentReadBuffer (Handle, (UINT8 *)DebugHeader + OFFSET_OF (DEBUG_PACKET_HEADER, Command), sizeof (DEBUG_PACKET_HEADER) - OFFSET_OF (DEBUG_PACKET_HEADER, Command), READ_PACKET_TIMEOUT) == 0) {
    //
    // Timeout occur, exit
    //
    DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Timeout in Debug Timer interrupt\n");
    return EFI_TIMEOUT;
  }

  Crc              = DebugHeader->Crc;
  DebugHeader->Crc = 0;
  if (CalculateCrc16 ((UINT8 *)DebugHeader, DebugHeader->Length, 0) != Crc) {
    DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Debug Timer CRC (%x) against (%x)\n", Crc, CalculateCrc16 ((UINT8 *)&DebugHeader, DebugHeader->Length, 0));
    DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *)DebugHeader, DebugHeader->Length);
    return EFI_CRC_ERROR;
  }

  Mailbox = GetMailboxPointer ();
  if (IS_REQUEST (DebugHeader)) {
    if (DebugHeader->SequenceNo == (UINT8)(Mailbox->HostSequenceNo + 1)) {
      //
      // Only update HostSequenceNo for new command packet
      //
      UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, DebugHeader->SequenceNo);
      return EFI_SUCCESS;
    }

    if (DebugHeader->SequenceNo == Mailbox->HostSequenceNo) {
      return EFI_SUCCESS;
    }
  }

  return EFI_DEVICE_ERROR;
}

/**
  Check if HOST is attached based on Mailbox.

  @retval TRUE        HOST is attached.
  @retval FALSE       HOST is not attached.

**/
BOOLEAN
IsHostAttached (
  VOID
  )
{
  return (BOOLEAN)(GetDebugFlag (DEBUG_AGENT_FLAG_HOST_ATTACHED) == 1);
}

/**
  Set HOST connect flag in Mailbox.

  @param[in] Attached        Attach status.

**/
VOID
SetHostAttached (
  IN BOOLEAN  Attached
  )
{
  DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Attach status is %d\n", Attached);
  SetDebugFlag (DEBUG_AGENT_FLAG_HOST_ATTACHED, (UINT32)Attached);
}

/**
  Set debug setting of Debug Agent in Mailbox.

  @param DebugSetting         Pointer to Debug Setting defined by transfer protocol.

  @retval RETURN_SUCCESS      The setting is set successfully.
  @retval RETURN_UNSUPPORTED  The Key value is not supported.

**/
RETURN_STATUS
SetDebugSetting (
  IN DEBUG_DATA_SET_DEBUG_SETTING  *DebugSetting
  )
{
  RETURN_STATUS  Status;

  Status = RETURN_SUCCESS;
  switch (DebugSetting->Key) {
    case DEBUG_AGENT_SETTING_SMM_ENTRY_BREAK:
      SetDebugFlag (DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI, DebugSetting->Value);
      break;
    case DEBUG_AGENT_SETTING_PRINT_ERROR_LEVEL:
      SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DebugSetting->Value);
      break;
    case DEBUG_AGENT_SETTING_BOOT_SCRIPT_ENTRY_BREAK:
      SetDebugFlag (DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT, DebugSetting->Value);
      break;
    default:
      Status = RETURN_UNSUPPORTED;
  }

  return Status;
}

/**
  Execute GO command.

  @param[in] CpuContext        Pointer to saved CPU context.

**/
VOID
CommandGo (
  IN DEBUG_CPU_CONTEXT  *CpuContext
  )
{
  IA32_EFLAGS32  *Eflags;

  Eflags          = (IA32_EFLAGS32 *)&CpuContext->Eflags;
  Eflags->Bits.TF = 0;
  Eflags->Bits.RF = 1;
}

/**
  Execute Stepping command.

  @param[in] CpuContext        Pointer to saved CPU context.

**/
VOID
CommandStepping (
  IN DEBUG_CPU_CONTEXT  *CpuContext
  )
{
  IA32_EFLAGS32  *Eflags;

  Eflags          = (IA32_EFLAGS32 *)&CpuContext->Eflags;
  Eflags->Bits.TF = 1;
  Eflags->Bits.RF = 1;
  //
  // Save and clear EFLAGS.IF to avoid interrupt happen when executing Stepping
  //
  SetDebugFlag (DEBUG_AGENT_FLAG_INTERRUPT_FLAG, Eflags->Bits.IF);
  Eflags->Bits.IF = 0;
  //
  // Set Stepping Flag
  //
  SetDebugFlag (DEBUG_AGENT_FLAG_STEPPING, 1);
}

/**
  Do some cleanup after Stepping command done.

  @param[in] CpuContext        Pointer to saved CPU context.

**/
VOID
CommandSteppingCleanup (
  IN DEBUG_CPU_CONTEXT  *CpuContext
  )
{
  IA32_EFLAGS32  *Eflags;

  Eflags = (IA32_EFLAGS32 *)&CpuContext->Eflags;
  //
  // Restore EFLAGS.IF
  //
  Eflags->Bits.IF = GetDebugFlag (DEBUG_AGENT_FLAG_INTERRUPT_FLAG);
  //
  // Clear Stepping flag
  //
  SetDebugFlag (DEBUG_AGENT_FLAG_STEPPING, 0);
}

/**
  Set debug register for hardware breakpoint.

  @param[in] CpuContext      Pointer to saved CPU context.
  @param[in] SetHwBreakpoint Hardware breakpoint to be set.

**/
VOID
SetDebugRegister (
  IN DEBUG_CPU_CONTEXT             *CpuContext,
  IN DEBUG_DATA_SET_HW_BREAKPOINT  *SetHwBreakpoint
  )
{
  UINT8  RegisterIndex;
  UINTN  Dr7Value;

  RegisterIndex = SetHwBreakpoint->Type.Index;

  //
  // Set debug address
  //
  *((UINTN *)&CpuContext->Dr0 + RegisterIndex) = (UINTN)SetHwBreakpoint->Address;

  Dr7Value = CpuContext->Dr7;

  //
  // Enable Gx, Lx
  //
  Dr7Value |= (UINTN)(0x3 << (RegisterIndex * 2));
  //
  // Set RWx and Lenx
  //
  Dr7Value &= (UINTN)(~(0xf << (16 + RegisterIndex * 4)));
  Dr7Value |= (UINTN)((SetHwBreakpoint->Type.Length << 2) | SetHwBreakpoint->Type.Access) << (16 + RegisterIndex * 4);
  //
  // Enable GE, LE
  //
  Dr7Value |= 0x300;

  CpuContext->Dr7 = Dr7Value;
}

/**
  Clear debug register for hardware breakpoint.

  @param[in] CpuContext        Pointer to saved CPU context.
  @param[in] ClearHwBreakpoint Hardware breakpoint to be cleared.

**/
VOID
ClearDebugRegister (
  IN DEBUG_CPU_CONTEXT               *CpuContext,
  IN DEBUG_DATA_CLEAR_HW_BREAKPOINT  *ClearHwBreakpoint
  )
{
  if ((ClearHwBreakpoint->IndexMask & BIT0) != 0) {
    CpuContext->Dr0  = 0;
    CpuContext->Dr7 &= (UINTN)(~(0x3 << 0));
  }

  if ((ClearHwBreakpoint->IndexMask & BIT1) != 0) {
    CpuContext->Dr1  = 0;
    CpuContext->Dr7 &= (UINTN)(~(0x3 << 2));
  }

  if ((ClearHwBreakpoint->IndexMask & BIT2) != 0) {
    CpuContext->Dr2  = 0;
    CpuContext->Dr7 &= (UINTN)(~(0x3 << 4));
  }

  if ((ClearHwBreakpoint->IndexMask & BIT3) != 0) {
    CpuContext->Dr3  = 0;
    CpuContext->Dr7 &= (UINTN)(~(0x3 << 6));
  }
}

/**
  Return the offset of FP / MMX / XMM registers in the FPU saved state by register index.

  @param[in]  Index    Register index.
  @param[out] Width    Register width returned.

  @return Offset in the FPU Save State.

**/
UINT16
ArchReadFxStatOffset (
  IN  UINT8  Index,
  OUT UINT8  *Width
  )
{
  if (Index < SOFT_DEBUGGER_REGISTER_ST0) {
    switch (Index) {
      case SOFT_DEBUGGER_REGISTER_FP_FCW:
        *Width = (UINT8)sizeof (UINT16);
        return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Fcw);

      case SOFT_DEBUGGER_REGISTER_FP_FSW:
        *Width = (UINT8)sizeof (UINT16);
        return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Fsw);

      case SOFT_DEBUGGER_REGISTER_FP_FTW:
        *Width = (UINT8)sizeof (UINT16);
        return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Ftw);

      case SOFT_DEBUGGER_REGISTER_FP_OPCODE:
        *Width = (UINT8)sizeof (UINT16);
        return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Opcode);

      case SOFT_DEBUGGER_REGISTER_FP_EIP:
        *Width = (UINT8)sizeof (UINT32);
        return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Eip);

      case SOFT_DEBUGGER_REGISTER_FP_CS:
        *Width = (UINT8)sizeof (UINT16);
        return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Cs);

      case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:
        *Width = (UINT8)sizeof (UINT32);
        return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, DataOffset);

      case SOFT_DEBUGGER_REGISTER_FP_DS:
        *Width = (UINT8)sizeof (UINT16);
        return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Ds);

      case SOFT_DEBUGGER_REGISTER_FP_MXCSR:
        *Width = (UINT8)sizeof (UINT32);
        return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Mxcsr);

      case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:
        *Width = (UINT8)sizeof (UINT32);
        return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Mxcsr_Mask);
    }
  }

  if (Index <= SOFT_DEBUGGER_REGISTER_ST7) {
    *Width = 10;
  } else if (Index <= SOFT_DEBUGGER_REGISTER_XMM15) {
    *Width = 16;
  } else {
    //
    // MMX register
    //
    *Width = 8;
    Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;
  }

  return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16;
}

/**
  Return the pointer of the register value in the CPU saved context.

  @param[in]  CpuContext         Pointer to saved CPU context.
  @param[in]  Index              Register index value.
  @param[out] Width              Data width to read.

  @return The pointer in the CPU saved context.

**/
UINT8 *
ArchReadRegisterBuffer (
  IN DEBUG_CPU_CONTEXT  *CpuContext,
  IN UINT8              Index,
  OUT UINT8             *Width
  )
{
  UINT8  *Buffer;

  if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {
    Buffer = (UINT8 *)CpuContext + OFFSET_OF (DEBUG_CPU_CONTEXT, Dr0) + Index * sizeof (UINTN);
    *Width = (UINT8)sizeof (UINTN);
  } else {
    //
    // FPU/MMX/XMM registers
    //
    Buffer = (UINT8 *)CpuContext + OFFSET_OF (DEBUG_CPU_CONTEXT, FxSaveState) + ArchReadFxStatOffset (Index, Width);
  }

  return Buffer;
}

/**
  Send the packet without data to HOST.

  @param[in] CommandType    Type of Command.
  @param[in] SequenceNo     Sequence number.

**/
VOID
SendPacketWithoutData (
  IN UINT8  CommandType,
  IN UINT8  SequenceNo
  )
{
  DEBUG_PACKET_HEADER  DebugHeader;
  DEBUG_PORT_HANDLE    Handle;

  Handle = GetDebugPortHandle ();

  DebugHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;
  DebugHeader.Command     = CommandType;
  DebugHeader.Length      = sizeof (DEBUG_PACKET_HEADER);
  DebugHeader.SequenceNo  = SequenceNo;
  DebugHeader.Crc         = 0;
  DebugHeader.Crc         = CalculateCrc16 ((UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER), 0);

  DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, TRUE, (UINT8 *)&DebugHeader, DebugHeader.Length);
  DebugPortWriteBuffer (Handle, (UINT8 *)&DebugHeader, DebugHeader.Length);
}

/**
  Send acknowledge packet to HOST.

  @param[in] AckCommand    Type of Acknowledge packet.

**/
VOID
SendAckPacket (
  IN UINT8  AckCommand
  )
{
  UINT8                SequenceNo;
  DEBUG_AGENT_MAILBOX  *Mailbox;

  if (AckCommand != DEBUG_COMMAND_OK) {
    //
    // This is not ACK OK packet
    //
    DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "Send ACK(%d)\n", AckCommand);
  }

  Mailbox    = GetMailboxPointer ();
  SequenceNo = Mailbox->HostSequenceNo;
  DebugAgentMsgPrint (DEBUG_AGENT_INFO, "SendAckPacket: SequenceNo = %x\n", SequenceNo);
  SendPacketWithoutData (AckCommand, SequenceNo);
  UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_LAST_ACK, AckCommand);
}

/**
  Decompress the Data in place.

  @param[in, out] Data   The compressed data buffer.
                         The buffer is assumed large enough to hold the uncompressed data.
  @param[in]      Length The length of the compressed data buffer.

  @return   The length of the uncompressed data buffer.
**/
UINT8
DecompressDataInPlace (
  IN OUT UINT8  *Data,
  IN UINTN      Length
  )
{
  UINTN   Index;
  UINT16  LastChar;
  UINTN   LastCharCount;
  UINT8   CurrentChar;

  LastChar      = (UINT16)-1;
  LastCharCount = 0;
  for (Index = 0; Index < Length; Index++) {
    CurrentChar = Data[Index];
    if (LastCharCount == 2) {
      LastCharCount = 0;
      CopyMem (&Data[Index + CurrentChar], &Data[Index + 1], Length - Index - 1);
      SetMem (&Data[Index], CurrentChar, (UINT8)LastChar);
      LastChar = (UINT16)-1;
      Index   += CurrentChar - 1;
      Length  += CurrentChar - 1;
    } else {
      if (LastChar != CurrentChar) {
        LastCharCount = 0;
      }

      LastCharCount++;
      LastChar = CurrentChar;
    }
  }

  ASSERT (Length <= DEBUG_DATA_MAXIMUM_REAL_DATA);

  return (UINT8)Length;
}

/**
  Receive valid packet from HOST.

  @param[out] InputPacket         Buffer to receive packet.
  @param[out] BreakReceived       TRUE means break-in symbol received.
                                  FALSE means break-in symbol not received.
  @param[out] IncompatibilityFlag If IncompatibilityFlag is not NULL, return
                                  TRUE:  Compatible packet received.
                                  FALSE: Incompatible packet received.
  @param[in]  Timeout             Time out value to wait for acknowledge from HOST.
                                  The unit is microsecond.
  @param[in]  SkipStartSymbol     TRUE:  Skip time out when reading start symbol.
                                  FALSE: Does not Skip time out when reading start symbol.

  @retval RETURN_SUCCESS   A valid package was received in InputPacket.
  @retval RETURN_TIMEOUT   Timeout occurs.

**/
RETURN_STATUS
ReceivePacket (
  OUT UINT8    *InputPacket,
  OUT BOOLEAN  *BreakReceived,
  OUT BOOLEAN  *IncompatibilityFlag  OPTIONAL,
  IN  UINTN    Timeout,
  IN  BOOLEAN  SkipStartSymbol
  )
{
  DEBUG_PACKET_HEADER  *DebugHeader;
  UINTN                Received;
  DEBUG_PORT_HANDLE    Handle;
  UINT16               Crc;
  UINTN                TimeoutForStartSymbol;

  Handle = GetDebugPortHandle ();
  if (SkipStartSymbol) {
    TimeoutForStartSymbol = 0;
  } else {
    TimeoutForStartSymbol = Timeout;
  }

  DebugHeader = (DEBUG_PACKET_HEADER *)InputPacket;
  while (TRUE) {
    //
    // Find the valid start symbol
    //
    Received = DebugAgentReadBuffer (Handle, &DebugHeader->StartSymbol, sizeof (DebugHeader->StartSymbol), TimeoutForStartSymbol);
    if (Received < sizeof (DebugHeader->StartSymbol)) {
      DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "DebugAgentReadBuffer(StartSymbol) timeout\n");
      return RETURN_TIMEOUT;
    }

    if ((DebugHeader->StartSymbol != DEBUG_STARTING_SYMBOL_NORMAL) && (DebugHeader->StartSymbol != DEBUG_STARTING_SYMBOL_COMPRESS)) {
      DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Invalid start symbol received [%02x]\n", DebugHeader->StartSymbol);
      continue;
    }

    //
    // Read Package header till field Length
    //
    Received = DebugAgentReadBuffer (
                 Handle,
                 (UINT8 *)DebugHeader + OFFSET_OF (DEBUG_PACKET_HEADER, Command),
                 OFFSET_OF (DEBUG_PACKET_HEADER, Length) + sizeof (DebugHeader->Length) - sizeof (DebugHeader->StartSymbol),
                 Timeout
                 );
    if (Received == 0) {
      DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "DebugAgentReadBuffer(Command) timeout\n");
      return RETURN_TIMEOUT;
    }

    if (DebugHeader->Length < sizeof (DEBUG_PACKET_HEADER)) {
      if (IncompatibilityFlag != NULL) {
        //
        // This is one old version debug packet format, set Incompatibility flag
        //
        *IncompatibilityFlag = TRUE;
      } else {
        //
        // Skip the bad small packet
        //
        continue;
      }
    } else {
      //
      // Read the payload data include the CRC field
      //
      Received = DebugAgentReadBuffer (Handle, &DebugHeader->SequenceNo, (UINT8)(DebugHeader->Length - OFFSET_OF (DEBUG_PACKET_HEADER, SequenceNo)), Timeout);
      if (Received == 0) {
        DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "DebugAgentReadBuffer(SequenceNo) timeout\n");
        return RETURN_TIMEOUT;
      }

      //
      // Calculate the CRC of Debug Packet
      //
      Crc              = DebugHeader->Crc;
      DebugHeader->Crc = 0;
      if (Crc == CalculateCrc16 ((UINT8 *)DebugHeader, DebugHeader->Length, 0)) {
        break;
      }

      DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "CRC Error (received CRC is %x)\n", Crc);
      DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *)DebugHeader, DebugHeader->Length);
    }
  }

  DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *)DebugHeader, DebugHeader->Length);

  if (DebugHeader->StartSymbol == DEBUG_STARTING_SYMBOL_COMPRESS) {
    DebugHeader->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;
    DebugHeader->Length      = DecompressDataInPlace (
                                 (UINT8 *)(DebugHeader + 1),
                                 DebugHeader->Length - sizeof (DEBUG_PACKET_HEADER)
                                 ) + sizeof (DEBUG_PACKET_HEADER);
  }

  return RETURN_SUCCESS;
}

/**
  Receive acknowledge packet OK from HOST in specified time.

  @param[in]  Command             The command type issued by TARGET.
  @param[in]  Timeout             Time out value to wait for acknowledge from HOST.
                                  The unit is microsecond.
  @param[out] BreakReceived       If BreakReceived is not NULL,
                                  TRUE is returned if break-in symbol received.
                                  FALSE is returned if break-in symbol not received.
  @param[out] IncompatibilityFlag If IncompatibilityFlag is not NULL, return
                                  TRUE:  Compatible packet received.
                                  FALSE: Incompatible packet received.

  @retval  RETURN_SUCCESS   Succeed to receive acknowledge packet from HOST,
                            the type of acknowledge packet saved in Ack.
  @retval  RETURN_TIMEOUT   Specified timeout value was up.

**/
RETURN_STATUS
SendCommandAndWaitForAckOK (
  IN  UINT8    Command,
  IN  UINTN    Timeout,
  OUT BOOLEAN  *BreakReceived  OPTIONAL,
  OUT BOOLEAN  *IncompatibilityFlag OPTIONAL
  )
{
  RETURN_STATUS        Status;
  UINT8                InputPacketBuffer[DEBUG_DATA_UPPER_LIMIT];
  DEBUG_PACKET_HEADER  *DebugHeader;
  UINT8                SequenceNo;
  UINT8                HostSequenceNo;
  UINT8                RetryCount;

  RetryCount  = 3;
  DebugHeader = (DEBUG_PACKET_HEADER *)InputPacketBuffer;
  Status      = RETURN_TIMEOUT;
  while (RetryCount > 0) {
    SequenceNo     = GetMailboxPointer ()->SequenceNo;
    HostSequenceNo = GetMailboxPointer ()->HostSequenceNo;
    SendPacketWithoutData (Command, SequenceNo);
    Status = ReceivePacket ((UINT8 *)DebugHeader, BreakReceived, IncompatibilityFlag, Timeout, FALSE);
    if (Status == RETURN_TIMEOUT) {
      if (Command == DEBUG_COMMAND_INIT_BREAK) {
        RetryCount--;
      } else {
        DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Timeout when waiting for ACK packet.\n");
      }

      continue;
    }

    ASSERT_EFI_ERROR (Status);
    //
    // Status == RETURN_SUCCESS
    //
    if ((DebugHeader->Command == DEBUG_COMMAND_OK) && (DebugHeader->SequenceNo == SequenceNo)) {
      //
      // Received Ack OK
      //
      UpdateMailboxContent (GetMailboxPointer (), DEBUG_MAILBOX_SEQUENCE_NO_INDEX, ++SequenceNo);
      return Status;
    }

    if ((DebugHeader->Command == DEBUG_COMMAND_GO) && ((DebugHeader->SequenceNo == HostSequenceNo) || (Command == DEBUG_COMMAND_INIT_BREAK))) {
      //
      // Received Old GO
      //
      if (Command == DEBUG_COMMAND_INIT_BREAK) {
        DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Receive GO() in last boot\n");
      }

      SendPacketWithoutData (DEBUG_COMMAND_OK, DebugHeader->SequenceNo);
    }
  }

  ASSERT (Command == DEBUG_COMMAND_INIT_BREAK);
  return Status;
}

/**
  Get current break cause.

  @param[in] Vector      Vector value of exception or interrupt.
  @param[in] CpuContext  Pointer to save CPU context.

  @return The type of break cause defined by XXXX

**/
UINT8
GetBreakCause (
  IN UINTN              Vector,
  IN DEBUG_CPU_CONTEXT  *CpuContext
  )
{
  UINT8  Cause;

  Cause = DEBUG_DATA_BREAK_CAUSE_UNKNOWN;

  switch (Vector) {
    case DEBUG_INT1_VECTOR:
    case DEBUG_INT3_VECTOR:

      if (Vector == DEBUG_INT1_VECTOR) {
        //
        // INT 1
        //
        if ((CpuContext->Dr6 & BIT14) != 0) {
          Cause = DEBUG_DATA_BREAK_CAUSE_STEPPING;
          //
          // DR6.BIT14 Indicates (when set) that the debug exception was
          // triggered by the single step execution mode.
          // The single-step mode is the highest priority debug exception.
          // This is single step, no need to check DR0, to ensure single step
          // work in PeCoffExtraActionLib (right after triggering a breakpoint
          // to report image load/unload).
          //
          return Cause;
        } else {
          Cause = DEBUG_DATA_BREAK_CAUSE_HW_BREAKPOINT;
        }
      } else {
        //
        // INT 3
        //
        Cause = DEBUG_DATA_BREAK_CAUSE_SW_BREAKPOINT;
      }

      switch (CpuContext->Dr0) {
        case IMAGE_LOAD_SIGNATURE:
        case IMAGE_UNLOAD_SIGNATURE:

          if (CpuContext->Dr3 == IO_PORT_BREAKPOINT_ADDRESS) {
            Cause = (UINT8)((CpuContext->Dr0 == IMAGE_LOAD_SIGNATURE) ?
                            DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD : DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD);
          }

          break;

        case SOFT_INTERRUPT_SIGNATURE:

          if (CpuContext->Dr1 == MEMORY_READY_SIGNATURE) {
            Cause           = DEBUG_DATA_BREAK_CAUSE_MEMORY_READY;
            CpuContext->Dr0 = 0;
          } else if (CpuContext->Dr1 == SYSTEM_RESET_SIGNATURE) {
            Cause           = DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET;
            CpuContext->Dr0 = 0;
          }

          break;

        default:
          break;
      }

      break;

    case DEBUG_TIMER_VECTOR:
      Cause = DEBUG_DATA_BREAK_CAUSE_USER_HALT;
      break;

    default:
      if (Vector < 20) {
        if (GetDebugFlag (DEBUG_AGENT_FLAG_STEPPING) == 1) {
          //
          // If stepping command is executing
          //
          Cause = DEBUG_DATA_BREAK_CAUSE_STEPPING;
        } else {
          Cause = DEBUG_DATA_BREAK_CAUSE_EXCEPTION;
        }
      }

      break;
  }

  return Cause;
}

/**
  Copy memory from source to destination with specified width.

  @param[out] Dest        A pointer to the destination buffer of the memory copy.
  @param[in]  Src         A pointer to the source buffer of the memory copy.
  @param[in]  Count       The number of data with specified width to copy from source to destination.
  @param[in]  Width       Data width in byte.

**/
VOID
CopyMemByWidth (
  OUT UINT8   *Dest,
  IN  UINT8   *Src,
  IN  UINT16  Count,
  IN  UINT8   Width
  )
{
  UINT8  *Destination;
  UINT8  *Source;
  INT8   Step;

  if (Src > Dest) {
    Destination = Dest;
    Source      = Src;
    Step        = Width;
  } else {
    //
    // Copy memory from tail to avoid memory overlap
    //
    Destination = Dest + (Count - 1) * Width;
    Source      = Src  + (Count - 1) * Width;
    Step        = -Width;
  }

  while (Count-- != 0) {
    switch (Width) {
      case 1:
        *(UINT8 *)Destination = MmioRead8 ((UINTN)Source);
        break;
      case 2:
        *(UINT16 *)Destination = MmioRead16 ((UINTN)Source);
        break;
      case 4:
        *(UINT32 *)Destination = MmioRead32 ((UINTN)Source);
        break;
      case 8:
        *(UINT64 *)Destination = MmioRead64 ((UINTN)Source);
        break;
      default:
        ASSERT (FALSE);
    }

    Source      += Step;
    Destination += Step;
  }
}

/**
  Compress the data buffer but do not modify the original buffer.

  The compressed data is directly send to the debug channel.
  Compressing in place doesn't work because the data may become larger
  during compressing phase. ("3 3 ..." --> "3 3 0 ...")
  The routine is expected to be called three times:
  1. Compute the length of the compressed data buffer;
  2. Compute the CRC of the compressed data buffer;
  3. Compress the data and send to the debug channel.

  @param[in]  Handle           The debug channel handle to send the compressed data buffer.
  @param[in]  Data             The data buffer.
  @param[in]  Length           The length of the data buffer.
  @param[in]  Send             TRUE to send the compressed data buffer.
  @param[out] CompressedLength Return the length of the compressed data buffer.
                               It may be larger than the Length in some cases.
  @param[out] CompressedCrc    Return the CRC of the compressed data buffer.
**/
VOID
CompressData (
  IN  DEBUG_PORT_HANDLE  Handle,
  IN  UINT8              *Data,
  IN  UINT8              Length,
  IN  BOOLEAN            Send,
  OUT UINTN              *CompressedLength   OPTIONAL,
  OUT UINT16             *CompressedCrc      OPTIONAL
  )
{
  UINTN  Index;
  UINT8  LastChar;
  UINT8  LastCharCount;
  UINT8  CurrentChar;
  UINTN  CompressedIndex;

  ASSERT (Length > 0);
  LastChar      = Data[0] + 1; // Just ensure it's different from the first byte.
  LastCharCount = 0;

  for (Index = 0, CompressedIndex = 0; Index <= Length; Index++) {
    if (Index < Length) {
      CurrentChar = Data[Index];
    } else {
      CurrentChar = (UINT8)LastChar + 1;  // just ensure it's different from LastChar
    }

    if (LastChar != CurrentChar) {
      if (LastCharCount == 1) {
        CompressedIndex++;
        if (CompressedCrc != NULL) {
          *CompressedCrc = CalculateCrc16 (&LastChar, 1, *CompressedCrc);
        }

        if (Send) {
          DebugPortWriteBuffer (Handle, &LastChar, 1);
        }
      } else if (LastCharCount >= 2) {
        CompressedIndex += 3;
        LastCharCount   -= 2;
        if (CompressedCrc != NULL) {
          *CompressedCrc = CalculateCrc16 (&LastChar, 1, *CompressedCrc);
          *CompressedCrc = CalculateCrc16 (&LastChar, 1, *CompressedCrc);
          *CompressedCrc = CalculateCrc16 (&LastCharCount, 1, *CompressedCrc);
        }

        if (Send) {
          DebugPortWriteBuffer (Handle, &LastChar, 1);
          DebugPortWriteBuffer (Handle, &LastChar, 1);
          DebugPortWriteBuffer (Handle, &LastCharCount, 1);
        }
      }

      LastCharCount = 0;
    }

    LastCharCount++;
    LastChar = CurrentChar;
  }

  if (CompressedLength != NULL) {
    *CompressedLength = CompressedIndex;
  }
}

/**
  Read memory with specified width and send packet with response data to HOST.

  @param[in] Data        Pointer to response data buffer.
  @param[in] Count       The number of data with specified Width.
  @param[in] Width       Data width in byte.
  @param[in] DebugHeader Pointer to a buffer for creating response packet and receiving ACK packet,
                         to minimize the stack usage.

  @retval RETURN_SUCCESS      Response data was sent successfully.

**/
RETURN_STATUS
ReadMemoryAndSendResponsePacket (
  IN UINT8                *Data,
  IN UINT16               Count,
  IN UINT8                Width,
  IN DEBUG_PACKET_HEADER  *DebugHeader
  )
{
  RETURN_STATUS      Status;
  BOOLEAN            LastPacket;
  DEBUG_PORT_HANDLE  Handle;
  UINT8              SequenceNo;
  UINTN              RemainingDataSize;
  UINT8              CurrentDataSize;
  UINTN              CompressedDataSize;

  Handle = GetDebugPortHandle ();

  RemainingDataSize = Count * Width;
  while (TRUE) {
    SequenceNo = GetMailboxPointer ()->HostSequenceNo;
    if (RemainingDataSize <= DEBUG_DATA_MAXIMUM_REAL_DATA) {
      //
      // If the remaining data is less one real packet size, this is the last data packet
      //
      CurrentDataSize      = (UINT8)RemainingDataSize;
      LastPacket           = TRUE;
      DebugHeader->Command = DEBUG_COMMAND_OK;
    } else {
      //
      // Data is too larger to be sent in one packet, calculate the actual data size could
      // be sent in one Maximum data packet
      //
      CurrentDataSize      = (DEBUG_DATA_MAXIMUM_REAL_DATA / Width) * Width;
      LastPacket           = FALSE;
      DebugHeader->Command = DEBUG_COMMAND_IN_PROGRESS;
    }

    //
    // Construct the rest Debug header
    //
    DebugHeader->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;
    DebugHeader->Length      = CurrentDataSize + sizeof (DEBUG_PACKET_HEADER);
    DebugHeader->SequenceNo  = SequenceNo;
    DebugHeader->Crc         = 0;
    CopyMemByWidth ((UINT8 *)(DebugHeader + 1), Data, CurrentDataSize / Width, Width);

    //
    // Compression/decompression support was added since revision 0.4.
    // Revision 0.3 shouldn't compress the packet.
    //
    if (PcdGet32 (PcdTransferProtocolRevision) >= DEBUG_AGENT_REVISION_04) {
      //
      // Get the compressed data size without modifying the packet.
      //
      CompressData (
        Handle,
        (UINT8 *)(DebugHeader + 1),
        CurrentDataSize,
        FALSE,
        &CompressedDataSize,
        NULL
        );
    } else {
      CompressedDataSize = CurrentDataSize;
    }

    if (CompressedDataSize < CurrentDataSize) {
      DebugHeader->Length      = (UINT8)CompressedDataSize + sizeof (DEBUG_PACKET_HEADER);
      DebugHeader->StartSymbol = DEBUG_STARTING_SYMBOL_COMPRESS;
      //
      // Compute the CRC of the packet head without modifying the packet.
      //
      DebugHeader->Crc = CalculateCrc16 ((UINT8 *)DebugHeader, sizeof (DEBUG_PACKET_HEADER), 0);
      CompressData (
        Handle,
        (UINT8 *)(DebugHeader + 1),
        CurrentDataSize,
        FALSE,
        NULL,
        &DebugHeader->Crc
        );
      //
      // Send out the packet head.
      //
      DebugPortWriteBuffer (Handle, (UINT8 *)DebugHeader, sizeof (DEBUG_PACKET_HEADER));
      //
      // Compress and send out the packet data.
      //
      CompressData (
        Handle,
        (UINT8 *)(DebugHeader + 1),
        CurrentDataSize,
        TRUE,
        NULL,
        NULL
        );
    } else {
      //
      // Calculate and fill the checksum, DebugHeader->Crc should be 0 before invoking CalculateCrc16 ()
      //
      DebugHeader->Crc = CalculateCrc16 ((UINT8 *)DebugHeader, DebugHeader->Length, 0);

      DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, TRUE, (UINT8 *)DebugHeader, DebugHeader->Length);

      DebugPortWriteBuffer (Handle, (UINT8 *)DebugHeader, DebugHeader->Length);
    }

    while (TRUE) {
      Status = ReceivePacket ((UINT8 *)DebugHeader, NULL, NULL, READ_PACKET_TIMEOUT, FALSE);
      if (Status == RETURN_TIMEOUT) {
        DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Timeout in SendDataResponsePacket()\n");
        break;
      }

      if ((DebugHeader->Command == DEBUG_COMMAND_OK) && (DebugHeader->SequenceNo == SequenceNo) && LastPacket) {
        //
        // If this is the last packet, return RETURN_SUCCESS.
        //
        return RETURN_SUCCESS;
      }

      if ((DebugHeader->Command == DEBUG_COMMAND_CONTINUE) && (DebugHeader->SequenceNo == (UINT8)(SequenceNo + 1))) {
        //
        // Calculate the rest data size
        //
        Data              += CurrentDataSize;
        RemainingDataSize -= CurrentDataSize;
        UpdateMailboxContent (GetMailboxPointer (), DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, DebugHeader->SequenceNo);
        break;
      }

      if (DebugHeader->SequenceNo >= SequenceNo) {
        DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Received one old or new command(SequenceNo is %x, last SequenceNo is %x)\n", SequenceNo, DebugHeader->SequenceNo);
        break;
      }
    }
  }
}

/**
  Send packet with response data to HOST.

  @param[in]      Data        Pointer to response data buffer.
  @param[in]      DataSize    Size of response data in byte.
  @param[in, out] DebugHeader Pointer to a buffer for creating response packet and receiving ACK packet,
                              to minimize the stack usage.

  @retval RETURN_SUCCESS      Response data was sent successfully.

**/
RETURN_STATUS
SendDataResponsePacket (
  IN UINT8                    *Data,
  IN UINT16                   DataSize,
  IN OUT DEBUG_PACKET_HEADER  *DebugHeader
  )
{
  return ReadMemoryAndSendResponsePacket (Data, DataSize, 1, DebugHeader);
}

/**
  Try to attach the HOST.

  Send init break packet to HOST:
  If no acknowledge received in specified Timeout, return RETURN_TIMEOUT.
  If received acknowledge, check the revision of HOST.
  Set Attach Flag if attach successfully.

  @param[in]  BreakCause     Break cause of this break event.
  @param[in]  Timeout        Time out value to wait for acknowledge from HOST.
                             The unit is microsecond.
  @param[out] BreakReceived  If BreakReceived is not NULL,
                             TRUE is returned if break-in symbol received.
                             FALSE is returned if break-in symbol not received.
**/
RETURN_STATUS
AttachHost (
  IN  UINT8    BreakCause,
  IN  UINTN    Timeout,
  OUT BOOLEAN  *BreakReceived
  )
{
  RETURN_STATUS      Status;
  DEBUG_PORT_HANDLE  Handle;
  BOOLEAN            IncompatibilityFlag;

  IncompatibilityFlag = FALSE;
  Handle              = GetDebugPortHandle ();

  //
  // Send init break and wait ack in Timeout
  //
  DebugPortWriteBuffer (Handle, (UINT8 *)mErrorMsgSendInitPacket, AsciiStrLen (mErrorMsgSendInitPacket));
  if (BreakCause == DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET) {
    Status = SendCommandAndWaitForAckOK (DEBUG_COMMAND_INIT_BREAK, Timeout, BreakReceived, &IncompatibilityFlag);
  } else {
    Status = SendCommandAndWaitForAckOK (DEBUG_COMMAND_ATTACH_BREAK, Timeout, BreakReceived, &IncompatibilityFlag);
  }

  if (IncompatibilityFlag) {
    //
    // If the incompatible Debug Packet received, the HOST should be running transfer protocol before PcdTransferProtocolRevision.
    // It could be UDK Debugger for Windows v1.1/v1.2 or for Linux v0.8/v1.2.
    //
    DebugPortWriteBuffer (Handle, (UINT8 *)mErrorMsgVersionAlert, AsciiStrLen (mErrorMsgVersionAlert));
    CpuDeadLoop ();
  }

  if (RETURN_ERROR (Status)) {
    DebugPortWriteBuffer (Handle, (UINT8 *)mErrorMsgConnectFail, AsciiStrLen (mErrorMsgConnectFail));
  } else {
    DebugPortWriteBuffer (Handle, (UINT8 *)mErrorMsgConnectOK, AsciiStrLen (mErrorMsgConnectOK));
    //
    // Set Attach flag
    //
    SetHostAttached (TRUE);
  }

  return Status;
}

/**
  Send Break point packet to HOST.

  Only the first breaking processor could sent BREAK_POINT packet.

  @param[in]  BreakCause     Break cause of this break event.
  @param[in]  ProcessorIndex Processor index value.
  @param[out] BreakReceived  If BreakReceived is not NULL,
                             TRUE is returned if break-in symbol received.
                             FALSE is returned if break-in symbol not received.

**/
VOID
SendBreakPacketToHost (
  IN  UINT8    BreakCause,
  IN  UINT32   ProcessorIndex,
  OUT BOOLEAN  *BreakReceived
  )
{
  UINT8              InputCharacter;
  DEBUG_PORT_HANDLE  Handle;

  Handle = GetDebugPortHandle ();

  if (IsHostAttached ()) {
    DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Send Break Packet to HOST.\n", ProcessorIndex);
    SendCommandAndWaitForAckOK (DEBUG_COMMAND_BREAK_POINT, READ_PACKET_TIMEOUT, BreakReceived, NULL);
  } else {
    DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Try to attach HOST.\n", ProcessorIndex);
    //
    // If HOST is not attached, try to attach it firstly.
    //
    //
    // Poll Attach symbols from HOST and ack OK
    //
    do {
      DebugAgentReadBuffer (Handle, &InputCharacter, 1, 0);
    } while (InputCharacter != DEBUG_STARTING_SYMBOL_ATTACH);

    SendAckPacket (DEBUG_COMMAND_OK);

    //
    // Try to attach HOST
    //
    while (AttachHost (BreakCause, 0, NULL) != RETURN_SUCCESS) {
    }
  }
}

/**
  The main function to process communication with HOST.

  It received the command packet from HOST, and sent response data packet to HOST.

  @param[in]      Vector         Vector value of exception or interrupt.
  @param[in, out] CpuContext     Pointer to saved CPU context.
  @param[in]      BreakReceived  TRUE means break-in symbol received.
                                 FALSE means break-in symbol not received.

**/
VOID
CommandCommunication (
  IN     UINTN              Vector,
  IN OUT DEBUG_CPU_CONTEXT  *CpuContext,
  IN     BOOLEAN            BreakReceived
  )
{
  RETURN_STATUS                      Status;
  UINT8                              InputPacketBuffer[DEBUG_DATA_UPPER_LIMIT + sizeof (UINT64) - 1];
  DEBUG_PACKET_HEADER                *DebugHeader;
  UINT8                              Width;
  UINT8                              Data8;
  UINT32                             Data32;
  UINT64                             Data64;
  DEBUG_DATA_READ_MEMORY             *MemoryRead;
  DEBUG_DATA_WRITE_MEMORY            *MemoryWrite;
  DEBUG_DATA_READ_IO                 *IoRead;
  DEBUG_DATA_WRITE_IO                *IoWrite;
  DEBUG_DATA_READ_REGISTER           *RegisterRead;
  DEBUG_DATA_WRITE_REGISTER          *RegisterWrite;
  UINT8                              *RegisterBuffer;
  DEBUG_DATA_READ_MSR                *MsrRegisterRead;
  DEBUG_DATA_WRITE_MSR               *MsrRegisterWrite;
  DEBUG_DATA_CPUID                   *Cpuid;
  DEBUG_DATA_RESPONSE_BREAK_CAUSE    BreakCause;
  DEBUG_DATA_RESPONSE_CPUID          CpuidResponse;
  DEBUG_DATA_SEARCH_SIGNATURE        *SearchSignature;
  DEBUG_DATA_RESPONSE_GET_EXCEPTION  Exception;
  DEBUG_DATA_RESPONSE_GET_REVISION   DebugAgentRevision;
  DEBUG_DATA_SET_VIEWPOINT           *SetViewPoint;
  BOOLEAN                            HaltDeferred;
  UINT32                             ProcessorIndex;
  DEBUG_AGENT_EXCEPTION_BUFFER       AgentExceptionBuffer;
  UINT32                             IssuedViewPoint;
  DEBUG_AGENT_MAILBOX                *Mailbox;
  UINT8                              *AlignedDataPtr;

  ProcessorIndex  = 0;
  IssuedViewPoint = 0;
  HaltDeferred    = BreakReceived;

  if (MultiProcessorDebugSupport ()) {
    ProcessorIndex = GetProcessorIndex ();
    SetCpuStopFlagByIndex (ProcessorIndex, TRUE);
    if (mDebugMpContext.ViewPointIndex == ProcessorIndex) {
      //
      // Only the current view processor could set AgentInProgress Flag.
      //
      IssuedViewPoint = ProcessorIndex;
    }
  }

  if (IssuedViewPoint == ProcessorIndex) {
    //
    // Set AgentInProgress Flag.
    //
    SetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS, 1);
  }

  while (TRUE) {
    if (MultiProcessorDebugSupport ()) {
      //
      // Check if the current processor is HOST view point
      //
      if (mDebugMpContext.ViewPointIndex != ProcessorIndex) {
        if (mDebugMpContext.RunCommandSet) {
          //
          // If HOST view point sets RUN flag, run GO command to leave
          //
          SetCpuStopFlagByIndex (ProcessorIndex, FALSE);
          CommandGo (CpuContext);
          break;
        } else {
          //
          // Run into loop again
          //
          CpuPause ();
          continue;
        }
      }
    }

    AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);

    DebugHeader = (DEBUG_PACKET_HEADER *)InputPacketBuffer;

    DebugAgentMsgPrint (DEBUG_AGENT_INFO, "TARGET: Try to get command from HOST...\n");
    Status = ReceivePacket ((UINT8 *)DebugHeader, &BreakReceived, NULL, READ_PACKET_TIMEOUT, TRUE);
    if ((Status != RETURN_SUCCESS) || !IS_REQUEST (DebugHeader)) {
      DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Get command[%x] sequenceno[%x] returned status is [%x] \n", DebugHeader->Command, DebugHeader->SequenceNo, Status);
      DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Get command failed or it's response packet not expected! \n");
      ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
      continue;
    }

    Mailbox = GetMailboxPointer ();
    if (DebugHeader->SequenceNo == Mailbox->HostSequenceNo) {
      DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Receive one old command[%x] against command[%x]\n", DebugHeader->SequenceNo, Mailbox->HostSequenceNo);
      SendAckPacket (Mailbox->LastAck);
      ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
      continue;
    } else if (DebugHeader->SequenceNo == (UINT8)(Mailbox->HostSequenceNo + 1)) {
      UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, (UINT8)DebugHeader->SequenceNo);
    } else {
      DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Receive one invalid command[%x] against command[%x]\n", DebugHeader->SequenceNo, Mailbox->HostSequenceNo);
      ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
      continue;
    }

    //
    // Save CPU content before executing HOST command
    //
    UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX, (UINT64)(UINTN)&AgentExceptionBuffer.JumpBuffer);
    if (SetJump (&AgentExceptionBuffer.JumpBuffer) != 0) {
      //
      // If HOST command failed, continue to wait for HOST's next command
      // If needed, agent could send exception info to HOST.
      //
      SendAckPacket (DEBUG_COMMAND_ABORT);
      ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
      continue;
    }

    DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Processor[%x]:Received one command(%x)\n", mDebugMpContext.ViewPointIndex, DebugHeader->Command);

    switch (DebugHeader->Command) {
      case DEBUG_COMMAND_HALT:
        SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED);
        HaltDeferred  = TRUE;
        BreakReceived = FALSE;
        Status        = RETURN_SUCCESS;
        break;

      case DEBUG_COMMAND_RESET:
        SendAckPacket (DEBUG_COMMAND_OK);
        SendAckPacket (DEBUG_COMMAND_OK);
        SendAckPacket (DEBUG_COMMAND_OK);
        ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);

        ResetCold ();
        //
        // Assume system resets in 2 seconds, otherwise send TIMEOUT packet.
        // PCD can be used if 2 seconds isn't long enough for some platforms.
        //
        MicroSecondDelay (2000000);
        UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, Mailbox->HostSequenceNo + 1);
        SendAckPacket (DEBUG_COMMAND_TIMEOUT);
        SendAckPacket (DEBUG_COMMAND_TIMEOUT);
        SendAckPacket (DEBUG_COMMAND_TIMEOUT);
        break;

      case DEBUG_COMMAND_GO:
        CommandGo (CpuContext);
        //
        // Clear Dr0 to avoid to be recognized as IMAGE_LOAD/_UNLOAD again when hitting a breakpoint after GO
        // If HOST changed Dr0 before GO, we will not change Dr0 here
        //
        Data8 = GetBreakCause (Vector, CpuContext);
        if ((Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD) || (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD)) {
          CpuContext->Dr0 = 0;
        }

        if (!HaltDeferred) {
          //
          // If no HALT command received when being in-active mode
          //
          if (MultiProcessorDebugSupport ()) {
            Data32 = FindNextPendingBreakCpu ();
            if (Data32 != -1) {
              //
              // If there are still others processors being in break state,
              // send OK packet to HOST to finish this go command
              //
              SendAckPacket (DEBUG_COMMAND_OK);
              CpuPause ();
              //
              // Set current view to the next breaking processor
              //
              mDebugMpContext.ViewPointIndex  = Data32;
              mDebugMpContext.BreakAtCpuIndex = mDebugMpContext.ViewPointIndex;
              SetCpuBreakFlagByIndex (mDebugMpContext.ViewPointIndex, FALSE);
              //
              // Send break packet to HOST to let HOST break again
              //
              SendBreakPacketToHost (DEBUG_DATA_BREAK_CAUSE_UNKNOWN, mDebugMpContext.BreakAtCpuIndex, &BreakReceived);
              //
              // Continue to run into loop to read command packet from HOST
              //
              ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
              break;
            }

            //
            // If no else processor break, set stop bitmask,
            // and set Running flag for all processors.
            //
            SetCpuStopFlagByIndex (ProcessorIndex, FALSE);
            SetCpuRunningFlag (TRUE);
            CpuPause ();
            //
            // Wait for all processors are in running state
            //
            while (TRUE) {
              if (IsAllCpuRunning ()) {
                break;
              }
            }

            //
            // Set BSP to be current view point.
            //
            SetDebugViewPoint (mDebugMpContext.BspIndex);
            CpuPause ();
            //
            // Clear breaking processor index and running flag
            //
            mDebugMpContext.BreakAtCpuIndex = (UINT32)(-1);
            SetCpuRunningFlag (FALSE);
          }

          //
          // Send OK packet to HOST to finish this go command
          //
          SendAckPacket (DEBUG_COMMAND_OK);

          ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);

          if (!IsHostAttached ()) {
            UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_SEQUENCE_NO_INDEX, 0);
            UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, 0);
          }

          return;
        } else {
          //
          // If received HALT command, need to defer the GO command
          //
          SendAckPacket (DEBUG_COMMAND_HALT_PROCESSED);
          HaltDeferred = FALSE;

          Vector = DEBUG_TIMER_VECTOR;
        }

        break;

      case DEBUG_COMMAND_BREAK_CAUSE:
        BreakCause.StopAddress = CpuContext->Eip;
        if (MultiProcessorDebugSupport () && (ProcessorIndex != mDebugMpContext.BreakAtCpuIndex)) {
          BreakCause.Cause = GetBreakCause (DEBUG_TIMER_VECTOR, CpuContext);
        } else {
          BreakCause.Cause = GetBreakCause (Vector, CpuContext);
        }

        SendDataResponsePacket ((UINT8 *)&BreakCause, (UINT16)sizeof (DEBUG_DATA_RESPONSE_BREAK_CAUSE), DebugHeader);
        break;

      case DEBUG_COMMAND_SET_HW_BREAKPOINT:
        SetDebugRegister (CpuContext, (DEBUG_DATA_SET_HW_BREAKPOINT *)(DebugHeader + 1));
        SendAckPacket (DEBUG_COMMAND_OK);
        break;

      case DEBUG_COMMAND_CLEAR_HW_BREAKPOINT:
        ClearDebugRegister (CpuContext, (DEBUG_DATA_CLEAR_HW_BREAKPOINT *)(DebugHeader + 1));
        SendAckPacket (DEBUG_COMMAND_OK);
        break;

      case DEBUG_COMMAND_SINGLE_STEPPING:
        CommandStepping (CpuContext);
        //
        // Clear Dr0 to avoid to be recognized as IMAGE_LOAD/_UNLOAD again when hitting a breakpoint after GO
        // If HOST changed Dr0 before GO, we will not change Dr0 here
        //
        Data8 = GetBreakCause (Vector, CpuContext);
        if ((Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD) || (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD)) {
          CpuContext->Dr0 = 0;
        }

        mDebugMpContext.BreakAtCpuIndex = (UINT32)(-1);
        ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
        //
        // Executing stepping command directly without sending ACK packet,
        // ACK packet will be sent after stepping done.
        //
        return;

      case DEBUG_COMMAND_SET_SW_BREAKPOINT:
        Data64                  = (UINTN)(((DEBUG_DATA_SET_SW_BREAKPOINT *)(DebugHeader + 1))->Address);
        Data8                   = *(UINT8 *)(UINTN)Data64;
        *(UINT8 *)(UINTN)Data64 = DEBUG_SW_BREAKPOINT_SYMBOL;
        Status                  = SendDataResponsePacket ((UINT8 *)&Data8, (UINT16)sizeof (UINT8), DebugHeader);
        break;

      case DEBUG_COMMAND_READ_MEMORY:
        MemoryRead = (DEBUG_DATA_READ_MEMORY *)(DebugHeader + 1);
        Status     = ReadMemoryAndSendResponsePacket ((UINT8 *)(UINTN)MemoryRead->Address, MemoryRead->Count, MemoryRead->Width, DebugHeader);
        break;

      case DEBUG_COMMAND_WRITE_MEMORY:
        MemoryWrite = (DEBUG_DATA_WRITE_MEMORY *)(DebugHeader + 1);
        //
        // Copy data into one memory with 8-byte alignment address
        //
        AlignedDataPtr = ALIGN_POINTER ((UINT8 *)&MemoryWrite->Data, sizeof (UINT64));
        if (AlignedDataPtr != (UINT8 *)&MemoryWrite->Data) {
          CopyMem (AlignedDataPtr, (UINT8 *)&MemoryWrite->Data, MemoryWrite->Count * MemoryWrite->Width);
        }

        CopyMemByWidth ((UINT8 *)(UINTN)MemoryWrite->Address, AlignedDataPtr, MemoryWrite->Count, MemoryWrite->Width);
        SendAckPacket (DEBUG_COMMAND_OK);
        break;

      case DEBUG_COMMAND_READ_IO:
        IoRead = (DEBUG_DATA_READ_IO *)(DebugHeader + 1);
        switch (IoRead->Width) {
          case 1:
            Data64 = IoRead8 ((UINTN)IoRead->Port);
            break;
          case 2:
            Data64 = IoRead16 ((UINTN)IoRead->Port);
            break;
          case 4:
            Data64 = IoRead32 ((UINTN)IoRead->Port);
            break;
          case 8:
            Data64 = IoRead64 ((UINTN)IoRead->Port);
            break;
          default:
            Data64 = (UINT64)-1;
        }

        Status = SendDataResponsePacket ((UINT8 *)&Data64, IoRead->Width, DebugHeader);
        break;

      case DEBUG_COMMAND_WRITE_IO:
        IoWrite = (DEBUG_DATA_WRITE_IO *)(DebugHeader + 1);
        switch (IoWrite->Width) {
          case 1:
            Data64 = IoWrite8 ((UINTN)IoWrite->Port, *(UINT8 *)&IoWrite->Data);
            break;
          case 2:
            Data64 = IoWrite16 ((UINTN)IoWrite->Port, *(UINT16 *)&IoWrite->Data);
            break;
          case 4:
            Data64 = IoWrite32 ((UINTN)IoWrite->Port, *(UINT32 *)&IoWrite->Data);
            break;
          case 8:
            Data64 = IoWrite64 ((UINTN)IoWrite->Port, *(UINT64 *)&IoWrite->Data);
            break;
          default:
            Data64 = (UINT64)-1;
        }

        SendAckPacket (DEBUG_COMMAND_OK);
        break;

      case DEBUG_COMMAND_READ_ALL_REGISTERS:
        Status = SendDataResponsePacket ((UINT8 *)CpuContext, sizeof (*CpuContext), DebugHeader);
        break;

      case DEBUG_COMMAND_READ_REGISTER:
        RegisterRead = (DEBUG_DATA_READ_REGISTER *)(DebugHeader + 1);

        if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_MAX) {
          RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterRead->Index, &Width);
          Status         = SendDataResponsePacket (RegisterBuffer, Width, DebugHeader);
        } else {
          Status = RETURN_UNSUPPORTED;
        }

        break;

      case DEBUG_COMMAND_WRITE_REGISTER:
        RegisterWrite = (DEBUG_DATA_WRITE_REGISTER *)(DebugHeader + 1);
        if (RegisterWrite->Index <= SOFT_DEBUGGER_REGISTER_MAX) {
          RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterWrite->Index, &Width);
          ASSERT (Width == RegisterWrite->Length);
          CopyMem (RegisterBuffer, RegisterWrite->Data, Width);
          SendAckPacket (DEBUG_COMMAND_OK);
        } else {
          Status = RETURN_UNSUPPORTED;
        }

        break;

      case DEBUG_COMMAND_ARCH_MODE:
        Data8  = DEBUG_ARCH_SYMBOL;
        Status = SendDataResponsePacket ((UINT8 *)&Data8, (UINT16)sizeof (UINT8), DebugHeader);
        break;

      case DEBUG_COMMAND_READ_MSR:
        MsrRegisterRead = (DEBUG_DATA_READ_MSR *)(DebugHeader + 1);
        Data64          = AsmReadMsr64 (MsrRegisterRead->Index);
        Status          = SendDataResponsePacket ((UINT8 *)&Data64, (UINT16)sizeof (UINT64), DebugHeader);
        break;

      case DEBUG_COMMAND_WRITE_MSR:
        MsrRegisterWrite = (DEBUG_DATA_WRITE_MSR *)(DebugHeader + 1);
        AsmWriteMsr64 (MsrRegisterWrite->Index, MsrRegisterWrite->Value);
        SendAckPacket (DEBUG_COMMAND_OK);
        break;

      case DEBUG_COMMAND_SET_DEBUG_SETTING:
        Status = SetDebugSetting ((DEBUG_DATA_SET_DEBUG_SETTING *)(DebugHeader + 1));
        if (Status == RETURN_SUCCESS) {
          SendAckPacket (DEBUG_COMMAND_OK);
        }

        break;

      case DEBUG_COMMAND_GET_REVISION:
        DebugAgentRevision.Revision     = PcdGet32 (PcdTransferProtocolRevision);
        DebugAgentRevision.Capabilities = DEBUG_AGENT_CAPABILITIES;
        Status                          = SendDataResponsePacket ((UINT8 *)&DebugAgentRevision, (UINT16)sizeof (DEBUG_DATA_RESPONSE_GET_REVISION), DebugHeader);
        break;

      case DEBUG_COMMAND_GET_EXCEPTION:
        Exception.ExceptionNum  = (UINT8)Vector;
        Exception.ExceptionData = (UINT32)CpuContext->ExceptionData;
        Status                  = SendDataResponsePacket ((UINT8 *)&Exception, (UINT16)sizeof (DEBUG_DATA_RESPONSE_GET_EXCEPTION), DebugHeader);
        break;

      case DEBUG_COMMAND_SET_VIEWPOINT:
        SetViewPoint = (DEBUG_DATA_SET_VIEWPOINT *)(DebugHeader + 1);
        if (MultiProcessorDebugSupport ()) {
          if (IsCpuStopped (SetViewPoint->ViewPoint)) {
            SetDebugViewPoint (SetViewPoint->ViewPoint);
            SendAckPacket (DEBUG_COMMAND_OK);
          } else {
            //
            // If CPU is not halted
            //
            SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);
          }
        } else if (SetViewPoint->ViewPoint == 0) {
          SendAckPacket (DEBUG_COMMAND_OK);
        } else {
          SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);
        }

        break;

      case DEBUG_COMMAND_GET_VIEWPOINT:
        Data32 = mDebugMpContext.ViewPointIndex;
        SendDataResponsePacket ((UINT8 *)&Data32, (UINT16)sizeof (UINT32), DebugHeader);
        break;

      case DEBUG_COMMAND_MEMORY_READY:
        Data8 = (UINT8)GetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY);
        SendDataResponsePacket (&Data8, (UINT16)sizeof (UINT8), DebugHeader);
        break;

      case DEBUG_COMMAND_DETACH:
        SetHostAttached (FALSE);
        SendAckPacket (DEBUG_COMMAND_OK);
        break;

      case DEBUG_COMMAND_CPUID:
        Cpuid = (DEBUG_DATA_CPUID *)(DebugHeader + 1);
        AsmCpuidEx (
          Cpuid->Eax,
          Cpuid->Ecx,
          &CpuidResponse.Eax,
          &CpuidResponse.Ebx,
          &CpuidResponse.Ecx,
          &CpuidResponse.Edx
          );
        SendDataResponsePacket ((UINT8 *)&CpuidResponse, (UINT16)sizeof (CpuidResponse), DebugHeader);
        break;

      case DEBUG_COMMAND_SEARCH_SIGNATURE:
        SearchSignature = (DEBUG_DATA_SEARCH_SIGNATURE *)(DebugHeader + 1);
        if ((SearchSignature->Alignment != 0) &&
            (SearchSignature->Alignment == GetPowerOfTwo32 (SearchSignature->Alignment))
            )
        {
          if (SearchSignature->Positive) {
            for (
                 Data64 = ALIGN_VALUE ((UINTN)SearchSignature->Start, SearchSignature->Alignment);
                 Data64 <= SearchSignature->Start + SearchSignature->Count - SearchSignature->DataLength;
                 Data64 += SearchSignature->Alignment
                 )
            {
              if (CompareMem ((VOID *)(UINTN)Data64, &SearchSignature->Data, SearchSignature->DataLength) == 0) {
                break;
              }
            }

            if (Data64 > SearchSignature->Start + SearchSignature->Count - SearchSignature->DataLength) {
              Data64 = (UINT64)-1;
            }
          } else {
            for (
                 Data64 = ALIGN_VALUE ((UINTN)SearchSignature->Start - SearchSignature->Alignment, SearchSignature->Alignment);
                 Data64 >= SearchSignature->Start - SearchSignature->Count;
                 Data64 -= SearchSignature->Alignment
                 )
            {
              if (CompareMem ((VOID *)(UINTN)Data64, &SearchSignature->Data, SearchSignature->DataLength) == 0) {
                break;
              }
            }

            if (Data64 < SearchSignature->Start - SearchSignature->Count) {
              Data64 = (UINT64)-1;
            }
          }

          SendDataResponsePacket ((UINT8 *)&Data64, (UINT16)sizeof (Data64), DebugHeader);
        } else {
          Status = RETURN_UNSUPPORTED;
        }

        break;

      default:
        SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);
        break;
    }

    if (Status == RETURN_UNSUPPORTED) {
      SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);
    } else if (Status != RETURN_SUCCESS) {
      SendAckPacket (DEBUG_COMMAND_ABORT);
    }

    ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
    CpuPause ();
  }
}

/**
  C function called in interrupt handler.

  @param[in] Vector      Vector value of exception or interrupt.
  @param[in] CpuContext  Pointer to save CPU context.

**/
VOID
EFIAPI
InterruptProcess (
  IN UINT32             Vector,
  IN DEBUG_CPU_CONTEXT  *CpuContext
  )
{
  UINT8                         InputCharacter;
  UINT8                         BreakCause;
  UINTN                         SavedEip;
  BOOLEAN                       BreakReceived;
  UINT32                        ProcessorIndex;
  UINT32                        CurrentDebugTimerInitCount;
  DEBUG_PORT_HANDLE             Handle;
  UINT8                         Data8;
  UINT8                         *Al;
  UINT32                        IssuedViewPoint;
  DEBUG_AGENT_EXCEPTION_BUFFER  *ExceptionBuffer;

  InputCharacter  = 0;
  ProcessorIndex  = 0;
  IssuedViewPoint = 0;
  BreakReceived   = FALSE;

  if (mSkipBreakpoint) {
    //
    // If Skip Breakpoint flag is set, means communication is disturbed by hardware SMI, we need to ignore the break points in SMM
    //
    if ((Vector == DEBUG_INT1_VECTOR) || (Vector == DEBUG_INT3_VECTOR)) {
      DebugPortWriteBuffer (GetDebugPortHandle (), (UINT8 *)mWarningMsgIngoreBreakpoint, AsciiStrLen (mWarningMsgIngoreBreakpoint));
      return;
    }
  }

  if (MultiProcessorDebugSupport ()) {
    ProcessorIndex = GetProcessorIndex ();
    //
    // If this processor has already halted before, need to check it later
    //
    if (IsCpuStopped (ProcessorIndex)) {
      IssuedViewPoint = ProcessorIndex;
    }
  }

  if ((IssuedViewPoint == ProcessorIndex) && (GetDebugFlag (DEBUG_AGENT_FLAG_STEPPING) != 1)) {
    //
    // Check if this exception is issued by Debug Agent itself
    // If yes, fill the debug agent exception buffer and LongJump() back to
    // the saved CPU content in CommandCommunication()
    // If exception is issued when executing Stepping, will be handled in
    // exception handle procedure.
    //
    if (GetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS) == 1) {
      DebugAgentMsgPrint (
        DEBUG_AGENT_ERROR,
        "Debug agent meet one Exception, ExceptionNum is %d, EIP = 0x%x.\n",
        Vector,
        (UINTN)CpuContext->Eip
        );
      ExceptionBuffer                                 = (DEBUG_AGENT_EXCEPTION_BUFFER *)(UINTN)GetMailboxPointer ()->ExceptionBufferPointer;
      ExceptionBuffer->ExceptionContent.ExceptionNum  = (UINT8)Vector;
      ExceptionBuffer->ExceptionContent.ExceptionData = (UINT32)CpuContext->ExceptionData;
      LongJump ((BASE_LIBRARY_JUMP_BUFFER *)(UINTN)(ExceptionBuffer), 1);
    }
  }

  if (MultiProcessorDebugSupport ()) {
    //
    // If RUN command is executing, wait for it done.
    //
    while (mDebugMpContext.RunCommandSet) {
      CpuPause ();
    }
  }

  Handle     = GetDebugPortHandle ();
  BreakCause = GetBreakCause (Vector, CpuContext);
  switch (Vector) {
    case DEBUG_INT1_VECTOR:
    case DEBUG_INT3_VECTOR:
      switch (BreakCause) {
        case DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET:
          if (AttachHost (BreakCause, READ_PACKET_TIMEOUT, &BreakReceived) != RETURN_SUCCESS) {
            //
            // Try to connect HOST, return if fails
            //
            break;
          }

          CommandCommunication (Vector, CpuContext, BreakReceived);
          break;

        case DEBUG_DATA_BREAK_CAUSE_STEPPING:
          //
          // Stepping is finished, send Ack package.
          //
          if (MultiProcessorDebugSupport ()) {
            mDebugMpContext.BreakAtCpuIndex = ProcessorIndex;
          }

          //
          // Clear Stepping Flag and restore EFLAGS.IF
          //
          CommandSteppingCleanup (CpuContext);
          SendAckPacket (DEBUG_COMMAND_OK);
          CommandCommunication (Vector, CpuContext, BreakReceived);
          break;

        case DEBUG_DATA_BREAK_CAUSE_MEMORY_READY:
          //
          // Memory is ready
          //
          SendCommandAndWaitForAckOK (DEBUG_COMMAND_MEMORY_READY, READ_PACKET_TIMEOUT, &BreakReceived, NULL);
          CommandCommunication (Vector, CpuContext, BreakReceived);
          break;

        case DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD:
        case DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD:
          //
          // Set AL to DEBUG_AGENT_IMAGE_CONTINUE
          //
          Al  = ArchReadRegisterBuffer (CpuContext, SOFT_DEBUGGER_REGISTER_AX, &Data8);
          *Al = DEBUG_AGENT_IMAGE_CONTINUE;

          if (!IsHostAttached ()) {
            //
            // If HOST is not connected for image load/unload, return
            //
            break;
          }

        //
        // Continue to run the following common code
        //

        case DEBUG_DATA_BREAK_CAUSE_HW_BREAKPOINT:
        case DEBUG_DATA_BREAK_CAUSE_SW_BREAKPOINT:
        default:
          //
          // Send Break packet to HOST
          //
          AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
          //
          // Only the first breaking processor could send BREAK_POINT to HOST
          //
          if (IsFirstBreakProcessor (ProcessorIndex)) {
            SendBreakPacketToHost (BreakCause, ProcessorIndex, &BreakReceived);
          }

          ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);

          if (Vector == DEBUG_INT3_VECTOR) {
            //
            // go back address located "0xCC"
            //
            CpuContext->Eip--;
            SavedEip = CpuContext->Eip;
            CommandCommunication (Vector, CpuContext, BreakReceived);
            if ((SavedEip == CpuContext->Eip) &&
                (*(UINT8 *)(UINTN)CpuContext->Eip == DEBUG_SW_BREAKPOINT_SYMBOL))
            {
              //
              // If this is not a software breakpoint set by HOST,
              // restore EIP
              //
              CpuContext->Eip++;
            }
          } else {
            CommandCommunication (Vector, CpuContext, BreakReceived);
          }

          break;
      }

      break;

    case DEBUG_TIMER_VECTOR:

      AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);

      if (MultiProcessorDebugSupport ()) {
        if (DebugAgentIsBsp (ProcessorIndex)) {
          //
          // If current processor is BSP, check Apic timer's init count if changed,
          // it may be re-written when switching BSP.
          // If it changed, re-initialize debug timer
          //
          CurrentDebugTimerInitCount = GetApicTimerInitCount ();
          if (mDebugMpContext.DebugTimerInitCount != CurrentDebugTimerInitCount) {
            InitializeDebugTimer (NULL, FALSE);
            SaveAndSetDebugTimerInterrupt (TRUE);
          }
        }

        if (!DebugAgentIsBsp (ProcessorIndex) || mDebugMpContext.IpiSentByAp) {
          ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
          //
          // If current processor is not BSP or this is one IPI sent by AP
          //
          if (mDebugMpContext.BreakAtCpuIndex != (UINT32)(-1)) {
            CommandCommunication (Vector, CpuContext, FALSE);
          }

          //
          // Clear EOI before exiting interrupt process routine.
          //
          SendApicEoi ();
          break;
        }
      }

      //
      // Only BSP could run here
      //
      while (TRUE) {
        //
        // If there is data in debug port, will check whether it is break(attach/break-in) symbol,
        // If yes, go into communication mode with HOST.
        // If no, exit interrupt process.
        //
        if (DebugReadBreakSymbol (Handle, &InputCharacter) == EFI_NOT_FOUND) {
          break;
        }

        if ((!IsHostAttached () && (InputCharacter == DEBUG_STARTING_SYMBOL_ATTACH)) ||
            (IsHostAttached () && (InputCharacter == DEBUG_COMMAND_HALT)) ||
            (IsHostAttached () && (InputCharacter == DEBUG_COMMAND_GO))
            )
        {
          DebugAgentMsgPrint (DEBUG_AGENT_VERBOSE, "Received data [%02x]\n", InputCharacter);
          //
          // Ack OK for break-in symbol
          //
          SendAckPacket (DEBUG_COMMAND_OK);

          //
          // If receive GO command in Debug Timer, means HOST may lost ACK packet before.
          //
          if (InputCharacter == DEBUG_COMMAND_GO) {
            break;
          }

          if (!IsHostAttached ()) {
            //
            // Try to attach HOST, if no ack received after 200ms, return
            //
            if (AttachHost (BreakCause, READ_PACKET_TIMEOUT, &BreakReceived) != RETURN_SUCCESS) {
              break;
            }
          }

          if (MultiProcessorDebugSupport ()) {
            if (FindNextPendingBreakCpu () != -1) {
              SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);
            } else {
              HaltOtherProcessors (ProcessorIndex);
            }
          }

          ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
          CommandCommunication (Vector, CpuContext, BreakReceived);
          AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
          break;
        }
      }

      //
      // Clear EOI before exiting interrupt process routine.
      //
      SendApicEoi ();

      ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);

      break;

    default:
      if (Vector <= DEBUG_EXCEPT_SIMD) {
        DebugAgentMsgPrint (
          DEBUG_AGENT_ERROR,
          "Exception happened, ExceptionNum is %d, EIP = 0x%x.\n",
          Vector,
          (UINTN)CpuContext->Eip
          );
        if (BreakCause == DEBUG_DATA_BREAK_CAUSE_STEPPING) {
          //
          // If exception happened when executing Stepping, send Ack package.
          // HOST consider Stepping command was finished.
          //
          if (MultiProcessorDebugSupport ()) {
            mDebugMpContext.BreakAtCpuIndex = ProcessorIndex;
          }

          //
          // Clear Stepping flag and restore EFLAGS.IF
          //
          CommandSteppingCleanup (CpuContext);
          SendAckPacket (DEBUG_COMMAND_OK);
        } else {
          //
          // Exception occurs, send Break packet to HOST
          //
          AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
          //
          // Only the first breaking processor could send BREAK_POINT to HOST
          //
          if (IsFirstBreakProcessor (ProcessorIndex)) {
            SendBreakPacketToHost (BreakCause, ProcessorIndex, &BreakReceived);
          }

          ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
        }

        CommandCommunication (Vector, CpuContext, BreakReceived);
      }

      break;
  }

  if (MultiProcessorDebugSupport ()) {
    //
    // Clear flag and wait for all processors run here
    //
    SetIpiSentByApFlag (FALSE);
    while (mDebugMpContext.RunCommandSet) {
      CpuPause ();
    }

    //
    // Only current (view) processor could clean up AgentInProgress flag.
    //
    if (mDebugMpContext.ViewPointIndex == ProcessorIndex) {
      IssuedViewPoint = mDebugMpContext.ViewPointIndex;
    }
  }

  if ((IssuedViewPoint == ProcessorIndex) && (GetDebugFlag (DEBUG_AGENT_FLAG_STEPPING) != 1)) {
    //
    // If the command is not stepping, clean up AgentInProgress flag
    //
    SetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS, 0);
  }

  return;
}
