/** @file
  Commond Debug Agent library implementition. 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>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "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 ((EFI_D_ERROR, "DebugAgent: Mailbox checksum error, stack or heap crashed!\n"));
    DEBUG ((EFI_D_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 foramtted in buffer
      //
      DestBuffer += AsciiSPrint(DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA - (DestBuffer - Buffer), "]\n");
      SendDebugMsgPacket (Buffer, DestBuffer - Buffer);
      break;
    }
  }
}

/**
  Read remaing 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 responsed 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 updagte 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;
}

/**
  Exectue 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 acknowlege 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 reveived 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 acknowlege from HOST.
                                  The unit is microsecond.
  @param[out] BreakReceived       If BreakReceived is not NULL,
                                  TRUE is retured if break-in symbol received.
                                  FALSE is retured if break-in symbol not received.
  @param[out] IncompatibilityFlag If IncompatibilityFlag is not NULL, return
                                  TRUE:  Compatible packet received.
                                  FALSE: Incompatible packet received.

  @retval  RETRUEN_SUCCESS  Succeed to receive acknowlege packet from HOST,
                            the type of acknowlege 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 speicifed 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 acknowlege received in specified Timeout, return RETURN_TIMEOUT.
  If received acknowlege, 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 acknowlege from HOST.
                             The unit is microsecond.
  @param[out] BreakReceived  If BreakReceived is not NULL,
                             TRUE is retured if break-in symbol received.
                             FALSE is retured 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 retured if break-in symbol received.
                             FALSE is retured 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 interrutp.
  @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] agaist 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 comamnd[%x] agaist command[%x]\n", DebugHeader->SequenceNo, Mailbox->HostSequenceNo);
      ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
      continue;
    }

    //
    // Save CPU content before executing HOST commond
    //
    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 reveived 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 interrutp.
  @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 alreay 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 commmand 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;
}

