/** @file
  SEC Core Debug Agent Library instance implementation.

  Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "SecPeiDebugAgentLib.h"

GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN  mSkipBreakpoint = FALSE;

GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_VECTOR_HANDOFF_INFO_PPI  mVectorHandoffInfoPpi = {
  &mVectorHandoffInfoDebugAgent[0]
};

//
// Ppis to be installed
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR  mVectorHandoffInfoPpiList[] = {
  {
    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
    &gEfiVectorHandoffInfoPpiGuid,
    &mVectorHandoffInfoPpi
  }
};

GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR  mDebugAgentMemoryDiscoveredNotifyList[1] = {
  {
    (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
    &gEfiPeiMemoryDiscoveredPpiGuid,
    DebugAgentCallbackMemoryDiscoveredPpi
  }
};

/**
  Check if debug agent support multi-processor.

  @retval TRUE    Multi-processor is supported.
  @retval FALSE   Multi-processor is not supported.

**/
BOOLEAN
MultiProcessorDebugSupport (
  VOID
  )
{
  return FALSE;
}

/**
  Read the Attach/Break-in symbols from the debug port.

  @param[in]  Handle         Pointer to Debug Port handle.
  @param[out] BreakSymbol    Returned break symbol.

  @retval EFI_SUCCESS        Read the symbol in BreakSymbol.
  @retval EFI_NOT_FOUND      No read the break symbol.

**/
EFI_STATUS
DebugReadBreakSymbol (
  IN  DEBUG_PORT_HANDLE  Handle,
  OUT UINT8              *BreakSymbol
  )
{
  EFI_STATUS           Status;
  DEBUG_PACKET_HEADER  DebugHeader;
  UINT8                *Data8;

  *BreakSymbol = 0;
  //
  // If Debug Port buffer has data, read it till it was break symbol or Debug Port buffer empty.
  //
  Data8 = (UINT8 *)&DebugHeader;
  while (TRUE) {
    //
    // If start symbol is not received
    //
    if (!DebugPortPollBuffer (Handle)) {
      //
      // If no data in Debug Port, exit
      //
      break;
    }

    //
    // Try to read the start symbol
    //
    DebugAgentReadBuffer (Handle, Data8, 1, 0);
    if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) {
      *BreakSymbol = *Data8;
      DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer attach symbol received %x", *BreakSymbol);
      return EFI_SUCCESS;
    }

    if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) {
      Status = ReadRemainingBreakPacket (Handle, &DebugHeader);
      if (Status == EFI_SUCCESS) {
        *BreakSymbol = DebugHeader.Command;
        DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer break symbol received %x", *BreakSymbol);
        return EFI_SUCCESS;
      }

      if (Status == EFI_TIMEOUT) {
        break;
      }
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Get the pointer to location saved Mailbox pointer from IDT entry.

**/
VOID *
GetLocationSavedMailboxPointerInIdtEntry (
  VOID
  )
{
  UINTN  *MailboxLocation;

  MailboxLocation = (UINTN *)GetExceptionHandlerInIdtEntry (DEBUG_MAILBOX_VECTOR);
  //
  // *MailboxLocation is the pointer to Mailbox
  //
  VerifyMailboxChecksum ((DEBUG_AGENT_MAILBOX *)(*MailboxLocation));
  return MailboxLocation;
}

/**
  Set the pointer of Mailbox into IDT entry before memory is ready.

  @param[in]  MailboxLocation    Pointer to location saved Mailbox pointer.

**/
VOID
SetLocationSavedMailboxPointerInIdtEntry (
  IN VOID  *MailboxLocation
  )
{
  SetExceptionHandlerInIdtEntry (DEBUG_MAILBOX_VECTOR, MailboxLocation);
}

/**
  Get the location of Mailbox pointer from the GUIDed HOB.

  @return Pointer to the location saved Mailbox pointer.

**/
UINT64 *
GetMailboxLocationFromHob (
  VOID
  )
{
  EFI_HOB_GUID_TYPE  *GuidHob;

  GuidHob = GetFirstGuidHob (&gEfiDebugAgentGuid);
  if (GuidHob == NULL) {
    return NULL;
  }

  return (UINT64 *)(GET_GUID_HOB_DATA (GuidHob));
}

/**
  Get Debug Agent Mailbox pointer.

  @return Mailbox pointer.

**/
DEBUG_AGENT_MAILBOX *
GetMailboxPointer (
  VOID
  )
{
  UINT64               DebugPortHandle;
  UINT64               *MailboxLocationInIdt;
  UINT64               *MailboxLocationInHob;
  DEBUG_AGENT_MAILBOX  *Mailbox;

  //
  // Get mailbox from IDT entry firstly
  //
  MailboxLocationInIdt = GetLocationSavedMailboxPointerInIdtEntry ();
  Mailbox              = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInIdt);
  //
  // Cannot used GetDebugFlag() to get Debug Flag to avoid GetMailboxPointer() nested
  //
  if ((Mailbox->DebugFlag.Bits.CheckMailboxInHob != 1) ||
      (Mailbox->DebugFlag.Bits.InitArch != DEBUG_ARCH_SYMBOL))
  {
    //
    // If mailbox was setup in SEC or the current CPU arch is different from the init arch
    // Debug Agent initialized, return the mailbox from IDT entry directly.
    // Otherwise, we need to check the mailbox location saved in GUIDed HOB further.
    //
    return Mailbox;
  }

  MailboxLocationInHob = GetMailboxLocationFromHob ();
  //
  // Compare mailbox in IDT entry with mailbox in HOB,
  // need to fix mailbox location if HOB moved by PEI CORE
  //
  if ((MailboxLocationInHob != MailboxLocationInIdt) && (MailboxLocationInHob != NULL)) {
    Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInHob);
    //
    // Fix up Debug Port handler and save new mailbox in IDT entry
    //
    Mailbox         = (DEBUG_AGENT_MAILBOX *)((UINTN)Mailbox + ((UINTN)(MailboxLocationInHob) - (UINTN)MailboxLocationInIdt));
    DebugPortHandle = (UINTN)Mailbox->DebugPortHandle + ((UINTN)(MailboxLocationInHob) - (UINTN)MailboxLocationInIdt);
    UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
    *MailboxLocationInHob = (UINT64)(UINTN)Mailbox;
    SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationInHob);
    //
    // Clean CheckMailboxInHob flag
    //
    Mailbox->DebugFlag.Bits.CheckMailboxInHob = 0;
    UpdateMailboxChecksum (Mailbox);
  }

  return Mailbox;
}

/**
  Get debug port handle.

  @return Debug port handle.

**/
DEBUG_PORT_HANDLE
GetDebugPortHandle (
  VOID
  )
{
  DEBUG_AGENT_MAILBOX  *DebugAgentMailbox;

  DebugAgentMailbox = GetMailboxPointer ();

  return (DEBUG_PORT_HANDLE)(UINTN)(DebugAgentMailbox->DebugPortHandle);
}

/**
  Debug Agent provided notify callback function on Memory Discovered PPI.

  @param[in] PeiServices      Indirect reference to the PEI Services Table.
  @param[in] NotifyDescriptor Address of the notification descriptor data structure.
  @param[in] Ppi              Address of the PPI that was installed.

  @retval EFI_SUCCESS If the function completed successfully.

**/
EFI_STATUS
EFIAPI
DebugAgentCallbackMemoryDiscoveredPpi (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  EFI_STATUS            Status;
  DEBUG_AGENT_MAILBOX   *Mailbox;
  BOOLEAN               InterruptStatus;
  EFI_PHYSICAL_ADDRESS  Address;
  DEBUG_AGENT_MAILBOX   *NewMailbox;
  UINT64                *MailboxLocationInHob;

  //
  // Save and disable original interrupt status
  //
  InterruptStatus = SaveAndDisableInterrupts ();

  //
  // Allocate ACPI NVS memory for new Mailbox and Debug Port Handle buffer
  //
  Status = PeiServicesAllocatePages (
             EfiACPIMemoryNVS,
             EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX) + PcdGet16 (PcdDebugPortHandleBufferSize)),
             &Address
             );
  ASSERT_EFI_ERROR (Status);
  NewMailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)Address;
  //
  // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox
  // and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core
  // reallocates the HOB.
  //
  Mailbox = GetMailboxPointer ();
  CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
  CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16 (PcdDebugPortHandleBufferSize));
  //
  // Update Mailbox Location pointer in GUIDed HOB and IDT entry with new one
  //
  MailboxLocationInHob = GetMailboxLocationFromHob ();
  ASSERT (MailboxLocationInHob != NULL);
  *MailboxLocationInHob = (UINT64)(UINTN)NewMailbox;
  SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationInHob);
  //
  // Update Debug Port Handle in new Mailbox
  //
  UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1));
  //
  // Set physical memory ready flag
  //
  SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);

  if (IsHostAttached ()) {
    //
    // Trigger one software interrupt to inform HOST
    //
    TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
  }

  //
  // Restore interrupt state.
  //
  SetInterruptState (InterruptStatus);

  return EFI_SUCCESS;
}

/**
  Initialize debug agent.

  This function is used to set up debug environment for SEC and PEI phase.

  If InitFlag is DEBUG_AGENT_INIT_PREMEM_SEC, it will override IDT table entries
  and initialize debug port. It will enable interrupt to support break-in feature.
  It will set up debug agent Mailbox in cache-as-ramfrom. It will be called before
  physical memory is ready.
  If InitFlag is DEBUG_AGENT_INIT_POSTMEM_SEC, debug agent will build one GUIDed
  HOB to copy debug agent Mailbox. It will be called after physical memory is ready.

  This function is used to set up debug environment to support source level debugging.
  If certain Debug Agent Library instance has to save some private data in the stack,
  this function must work on the mode that doesn't return to the caller, then
  the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one
  function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is
  responsible to invoke the passing-in function at the end of InitializeDebugAgent().

  If the parameter Function is not NULL, Debug Agent Library instance will invoke it by
  passing in the Context to be its parameter.

  If Function() is NULL, Debug Agent Library instance will return after setup debug
  environment.

  @param[in] InitFlag     Init flag is used to decide the initialize process.
  @param[in] Context      Context needed according to InitFlag; it was optional.
  @param[in] Function     Continue function called by debug agent library; it was
                          optional.

**/
VOID
EFIAPI
InitializeDebugAgent (
  IN UINT32                InitFlag,
  IN VOID                  *Context  OPTIONAL,
  IN DEBUG_AGENT_CONTINUE  Function  OPTIONAL
  )
{
  DEBUG_AGENT_MAILBOX              *Mailbox;
  DEBUG_AGENT_MAILBOX              *NewMailbox;
  DEBUG_AGENT_MAILBOX              MailboxInStack;
  DEBUG_AGENT_PHASE2_CONTEXT       Phase2Context;
  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  *DebugAgentContext;
  EFI_STATUS                       Status;
  IA32_DESCRIPTOR                  *Ia32Idtr;
  IA32_IDT_ENTRY                   *Ia32IdtEntry;
  UINT64                           DebugPortHandle;
  UINT64                           MailboxLocation;
  UINT64                           *MailboxLocationPointer;
  EFI_PHYSICAL_ADDRESS             Address;
  UINT32                           DebugTimerFrequency;
  BOOLEAN                          CpuInterruptState;

  //
  // Disable interrupts and save current interrupt state
  //
  CpuInterruptState = SaveAndDisableInterrupts ();

  switch (InitFlag) {
    case DEBUG_AGENT_INIT_PREMEM_SEC:

      InitializeDebugIdt ();

      MailboxLocation = (UINT64)(UINTN)&MailboxInStack;
      Mailbox         = &MailboxInStack;
      ZeroMem ((VOID *)Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
      //
      // Get and save debug port handle and set the length of memory block.
      //
      SetLocationSavedMailboxPointerInIdtEntry (&MailboxLocation);
      //
      // Force error message could be printed during the first shakehand between Target/HOST.
      //
      SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DEBUG_AGENT_ERROR);
      //
      // Save init arch type when debug agent initialized
      //
      SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL);
      //
      // Initialize Debug Timer hardware and save its frequency
      //
      InitializeDebugTimer (&DebugTimerFrequency, TRUE);
      UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);

      Phase2Context.InitFlag = InitFlag;
      Phase2Context.Context  = Context;
      Phase2Context.Function = Function;
      DebugPortInitialize ((VOID *)&Phase2Context, InitializeDebugAgentPhase2);
      //
      // If reaches here, it means Debug Port initialization failed.
      //
      DEBUG ((DEBUG_ERROR, "Debug Agent: Debug port initialization failed.\n"));

      break;

    case DEBUG_AGENT_INIT_POSTMEM_SEC:
      Mailbox = GetMailboxPointer ();
      //
      // Memory has been ready
      //
      SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
      if (IsHostAttached ()) {
        //
        // Trigger one software interrupt to inform HOST
        //
        TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
      }

      //
      // Install Vector Handoff Info PPI to persist vectors used by Debug Agent
      //
      Status = PeiServicesInstallPpi (&mVectorHandoffInfoPpiList[0]);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "DebugAgent: Failed to install Vector Handoff Info PPI!\n"));
        CpuDeadLoop ();
      }

      //
      // Fix up Debug Port handle address and mailbox address
      //
      DebugAgentContext = (DEBUG_AGENT_CONTEXT_POSTMEM_SEC *)Context;
      if (DebugAgentContext != NULL) {
        DebugPortHandle = (UINT64)(UINT32)(Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset);
        UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
        Mailbox         = (DEBUG_AGENT_MAILBOX *)((UINTN)Mailbox + DebugAgentContext->StackMigrateOffset);
        MailboxLocation = (UINT64)(UINTN)Mailbox;
        //
        // Build mailbox location in HOB and fix-up its address
        //
        MailboxLocationPointer = BuildGuidDataHob (
                                   &gEfiDebugAgentGuid,
                                   &MailboxLocation,
                                   sizeof (UINT64)
                                   );
        MailboxLocationPointer = (UINT64 *)((UINTN)MailboxLocationPointer + DebugAgentContext->HeapMigrateOffset);
      } else {
        //
        // DebugAgentContext is NULL. Then, Mailbox can directly be copied into memory.
        // Allocate ACPI NVS memory for new Mailbox and Debug Port Handle buffer
        //
        Status = PeiServicesAllocatePages (
                   EfiACPIMemoryNVS,
                   EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX) + PcdGet16 (PcdDebugPortHandleBufferSize)),
                   &Address
                   );
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "DebugAgent: Failed to allocate pages!\n"));
          CpuDeadLoop ();
        }

        NewMailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)Address;
        //
        // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox
        // and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core
        // reallocates the HOB.
        //
        CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
        CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16 (PcdDebugPortHandleBufferSize));
        UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1));
        MailboxLocation = (UINT64)(UINTN)NewMailbox;
        //
        // Build mailbox location in HOB
        //
        MailboxLocationPointer = BuildGuidDataHob (
                                   &gEfiDebugAgentGuid,
                                   &MailboxLocation,
                                   sizeof (UINT64)
                                   );
      }

      //
      // Update IDT entry to save the location saved mailbox pointer
      //
      SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);
      break;

    case DEBUG_AGENT_INIT_PEI:
      if (Context == NULL) {
        DEBUG ((DEBUG_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
        CpuDeadLoop ();
      }

      //
      // Check if Debug Agent has initialized before
      //
      if (IsDebugAgentInitialzed ()) {
        DEBUG ((DEBUG_WARN, "Debug Agent: It has already initialized in SEC Core!\n"));
        break;
      }

      //
      // Install Vector Handoff Info PPI to persist vectors used by Debug Agent
      //
      Status = PeiServicesInstallPpi (&mVectorHandoffInfoPpiList[0]);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "DebugAgent: Failed to install Vector Handoff Info PPI!\n"));
        CpuDeadLoop ();
      }

      //
      // Set up IDT entries
      //
      InitializeDebugIdt ();
      //
      // Build mailbox in HOB and setup Mailbox Set In Pei flag
      //
      Mailbox = AllocateZeroPool (sizeof (DEBUG_AGENT_MAILBOX));
      if (Mailbox == NULL) {
        DEBUG ((DEBUG_ERROR, "DebugAgent: Failed to allocate memory!\n"));
        CpuDeadLoop ();
      } else {
        MailboxLocation        = (UINT64)(UINTN)Mailbox;
        MailboxLocationPointer = BuildGuidDataHob (
                                   &gEfiDebugAgentGuid,
                                   &MailboxLocation,
                                   sizeof (UINT64)
                                   );
        //
        // Initialize Debug Timer hardware and save its frequency
        //
        InitializeDebugTimer (&DebugTimerFrequency, TRUE);
        UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);
        //
        // Update IDT entry to save the location pointer saved mailbox pointer
        //
        SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);
      }

      //
      // Save init arch type when debug agent initialized
      //
      SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL);
      //
      // Register for a callback once memory has been initialized.
      // If memory has been ready, the callback function will be invoked immediately
      //
      Status = PeiServicesNotifyPpi (&mDebugAgentMemoryDiscoveredNotifyList[0]);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "DebugAgent: Failed to register memory discovered callback function!\n"));
        CpuDeadLoop ();
      }

      //
      // Set HOB check flag if memory has not been ready yet
      //
      if (GetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY) == 0) {
        SetDebugFlag (DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB, 1);
      }

      Phase2Context.InitFlag = InitFlag;
      Phase2Context.Context  = Context;
      Phase2Context.Function = Function;
      DebugPortInitialize ((VOID *)&Phase2Context, InitializeDebugAgentPhase2);

      FindAndReportModuleImageInfo (4);

      break;

    case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64:
      if (Context == NULL) {
        DEBUG ((DEBUG_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
        CpuDeadLoop ();
      } else {
        Ia32Idtr               =  (IA32_DESCRIPTOR *)Context;
        Ia32IdtEntry           = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
        MailboxLocationPointer = (UINT64 *)((UINTN)Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +
                                            ((UINTN)Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));
        Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationPointer);
        //
        // Mailbox should valid and setup before executing thunk code
        //
        VerifyMailboxChecksum (Mailbox);

        DebugPortHandle = (UINT64)(UINTN)DebugPortInitialize ((VOID *)(UINTN)Mailbox->DebugPortHandle, NULL);
        UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
        //
        // Set up IDT entries
        //
        InitializeDebugIdt ();
        //
        // Update IDT entry to save location pointer saved the mailbox pointer
        //
        SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);

        FindAndReportModuleImageInfo (4);
      }

      break;

    default:
      //
      // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this
      // Debug Agent library instance.
      //
      DEBUG ((DEBUG_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));
      CpuDeadLoop ();
      break;
  }

  if (InitFlag == DEBUG_AGENT_INIT_POSTMEM_SEC) {
    //
    // Restore CPU Interrupt state and keep debug timer interrupt state as is
    // in DEBUG_AGENT_INIT_POSTMEM_SEC case
    //
    SetInterruptState (CpuInterruptState);
  } else {
    //
    // Enable Debug Timer interrupt
    //
    SaveAndSetDebugTimerInterrupt (TRUE);
    //
    // Enable CPU interrupts so debug timer interrupts can be delivered
    //
    EnableInterrupts ();
  }

  //
  // If Function is not NULL, invoke it always whatever debug agent was initialized successfully or not.
  //
  if (Function != NULL) {
    Function (Context);
  }

  //
  // Set return status for DEBUG_AGENT_INIT_PEI
  //
  if ((InitFlag == DEBUG_AGENT_INIT_PEI) && (Context != NULL)) {
    *(EFI_STATUS *)Context = EFI_SUCCESS;
  }
}

/**
  Caller provided function to be invoked at the end of DebugPortInitialize().

  Refer to the description for DebugPortInitialize() for more details.

  @param[in] Context           The first input argument of DebugPortInitialize().
  @param[in] DebugPortHandle   Debug port handle created by Debug Communication Library.

**/
VOID
EFIAPI
InitializeDebugAgentPhase2 (
  IN VOID               *Context,
  IN DEBUG_PORT_HANDLE  DebugPortHandle
  )
{
  DEBUG_AGENT_PHASE2_CONTEXT  *Phase2Context;
  UINT64                      *MailboxLocation;
  DEBUG_AGENT_MAILBOX         *Mailbox;
  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
  UINT16                      BufferSize;
  UINT64                      NewDebugPortHandle;

  Phase2Context   = (DEBUG_AGENT_PHASE2_CONTEXT *)Context;
  MailboxLocation = GetLocationSavedMailboxPointerInIdtEntry ();
  Mailbox         = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
  BufferSize      = PcdGet16 (PcdDebugPortHandleBufferSize);
  if ((Phase2Context->InitFlag == DEBUG_AGENT_INIT_PEI) && (BufferSize != 0)) {
    NewDebugPortHandle = (UINT64)(UINTN)AllocateCopyPool (BufferSize, DebugPortHandle);
  } else {
    NewDebugPortHandle = (UINT64)(UINTN)DebugPortHandle;
  }

  UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, NewDebugPortHandle);

  //
  // Trigger one software interrupt to inform HOST
  //
  TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);

  if (Phase2Context->InitFlag == DEBUG_AGENT_INIT_PREMEM_SEC) {
    //
    // If Temporary RAM region is below 128 MB, then send message to
    // host to disable low memory filtering.
    //
    SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Phase2Context->Context;
    if (((UINTN)SecCoreData->TemporaryRamBase < BASE_128MB) && IsHostAttached ()) {
      SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
      TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
    }

    //
    // Enable Debug Timer interrupt
    //
    SaveAndSetDebugTimerInterrupt (TRUE);
    //
    // Enable CPU interrupts so debug timer interrupts can be delivered
    //
    EnableInterrupts ();
    //
    // Call continuation function if it is not NULL.
    //
    Phase2Context->Function (Phase2Context->Context);
  }
}
