/** @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 - 2017, 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 (IsBsp (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 (!IsBsp (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;
}

