/** @file
  Debug Agent library implementation for Dxe Core and Dxr modules.

  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
  Copyright (c) Microsoft Corporation.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DxeDebugAgentLib.h"

DEBUG_AGENT_MAILBOX       mMailbox;
DEBUG_AGENT_MAILBOX       *mMailboxPointer = NULL;
IA32_IDT_GATE_DESCRIPTOR  mIdtEntryTable[33];
BOOLEAN                   mDxeCoreFlag                = FALSE;
BOOLEAN                   mMultiProcessorDebugSupport = FALSE;
VOID                      *mSavedIdtTable             = NULL;
UINTN                     mSaveIdtTableSize           = 0;
BOOLEAN                   mDebugAgentInitialized      = FALSE;
BOOLEAN                   mSkipBreakpoint             = FALSE;

/**
  Check if debug agent support multi-processor.

  @retval TRUE    Multi-processor is supported.
  @retval FALSE   Multi-processor is not supported.

**/
BOOLEAN
MultiProcessorDebugSupport (
  VOID
  )
{
  return mMultiProcessorDebugSupport;
}

/**
  Internal constructor worker function.

  It will register one callback function on EFI PCD Protocol.
  It will allocate the NVS memory to store Mailbox and install configuration table
  in system table to store its pointer.

**/
VOID
InternalConstructorWorker (
  VOID
  )
{
  EFI_STATUS               Status;
  EFI_PHYSICAL_ADDRESS     Address;
  BOOLEAN                  DebugTimerInterruptState;
  DEBUG_AGENT_MAILBOX      *Mailbox;
  DEBUG_AGENT_MAILBOX      *NewMailbox;
  EFI_HOB_GUID_TYPE        *GuidHob;
  EFI_VECTOR_HANDOFF_INFO  *VectorHandoffInfo;

  //
  // Check persisted vector handoff info
  //
  Status  = EFI_SUCCESS;
  GuidHob = GetFirstGuidHob (&gEfiVectorHandoffInfoPpiGuid);
  if ((GuidHob != NULL) && !mDxeCoreFlag) {
    //
    // Check if configuration table is installed or not if GUIDed HOB existed,
    // only when Debug Agent is not linked by DXE Core
    //
    Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **)&VectorHandoffInfo);
  }

  if ((GuidHob == NULL) || (Status != EFI_SUCCESS)) {
    //
    // Install configuration table for persisted vector handoff info if GUIDed HOB cannot be found or
    // configuration table does not exist
    //
    Status = gBS->InstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *)&mVectorHandoffInfoDebugAgent[0]);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "DebugAgent: Cannot install configuration table for persisted vector handoff info!\n"));
      CpuDeadLoop ();
    }
  }

  //
  // Install EFI Serial IO protocol on debug port
  //
  InstallSerialIo ();

  Address = 0;
  Status  = gBS->AllocatePages (
                   AllocateAnyPages,
                   EfiACPIMemoryNVS,
                   EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX) + PcdGet16 (PcdDebugPortHandleBufferSize)),
                   &Address
                   );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "DebugAgent: Cannot install configuration table for mailbox!\n"));
    CpuDeadLoop ();
  }

  DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);

  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 may be free at runtime, SMM debug agent needs to access them
  //
  Mailbox = GetMailboxPointer ();
  CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
  CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16 (PcdDebugPortHandleBufferSize));
  //
  // Update Debug Port Handle in new Mailbox
  //
  UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1));
  mMailboxPointer = NewMailbox;

  DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);

  Status = gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *)mMailboxPointer);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "DebugAgent: Failed to install configuration for mailbox!\n"));
    CpuDeadLoop ();
  }
}

/**
  Debug Agent constructor function.

  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.
  @param[in]  SystemTable   A pointer to the EFI System Table.

  @retval  RETURN_SUCCESS  When this function completed.

**/
RETURN_STATUS
EFIAPI
DxeDebugAgentLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  if (mDxeCoreFlag) {
    //
    // Invoke internal constructor function only when DXE core links this library instance
    //
    InternalConstructorWorker ();
  }

  return RETURN_SUCCESS;
}

/**
  Get the pointer to Mailbox from the configuration table.

  @return Pointer to Mailbox.

**/
DEBUG_AGENT_MAILBOX *
GetMailboxFromConfigurationTable (
  VOID
  )
{
  EFI_STATUS           Status;
  DEBUG_AGENT_MAILBOX  *Mailbox;

  Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **)&Mailbox);
  if ((Status == EFI_SUCCESS) && (Mailbox != NULL)) {
    VerifyMailboxChecksum (Mailbox);
    return Mailbox;
  } else {
    return NULL;
  }
}

/**
  Get the pointer to Mailbox from the GUIDed HOB.

  @param[in]  HobStart      The starting HOB pointer to search from.

  @return Pointer to Mailbox.

**/
DEBUG_AGENT_MAILBOX *
GetMailboxFromHob (
  IN VOID  *HobStart
  )
{
  EFI_HOB_GUID_TYPE    *GuidHob;
  UINT64               *MailboxLocation;
  DEBUG_AGENT_MAILBOX  *Mailbox;

  GuidHob = GetNextGuidHob (&gEfiDebugAgentGuid, HobStart);
  if (GuidHob == NULL) {
    return NULL;
  }

  MailboxLocation = (UINT64 *)(GET_GUID_HOB_DATA (GuidHob));
  Mailbox         = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
  VerifyMailboxChecksum (Mailbox);

  return Mailbox;
}

/**
  Get Debug Agent Mailbox pointer.

  @return Mailbox pointer.

**/
DEBUG_AGENT_MAILBOX *
GetMailboxPointer (
  VOID
  )
{
  AcquireMpSpinLock (&mDebugMpContext.MailboxSpinLock);
  VerifyMailboxChecksum (mMailboxPointer);
  ReleaseMpSpinLock (&mDebugMpContext.MailboxSpinLock);
  return mMailboxPointer;
}

/**
  Get debug port handle.

  @return Debug port handle.

**/
DEBUG_PORT_HANDLE
GetDebugPortHandle (
  VOID
  )
{
  return (DEBUG_PORT_HANDLE)(UINTN)(GetMailboxPointer ()->DebugPortHandle);
}

/**
  Worker function to set up Debug Agent environment.

  This function will set up IDT table and initialize the IDT entries and
  initialize CPU LOCAL APIC timer.
  It also tries to connect HOST if Debug Agent was not initialized before.

  @param[in] Mailbox        Pointer to Mailbox.

**/
VOID
SetupDebugAgentEnvironment (
  IN DEBUG_AGENT_MAILBOX  *Mailbox
  )
{
  IA32_DESCRIPTOR  Idtr;
  UINT16           IdtEntryCount;
  UINT64           DebugPortHandle;
  UINT32           DebugTimerFrequency;

  if (mMultiProcessorDebugSupport) {
    InitializeSpinLock (&mDebugMpContext.MpContextSpinLock);
    InitializeSpinLock (&mDebugMpContext.DebugPortSpinLock);
    InitializeSpinLock (&mDebugMpContext.MailboxSpinLock);
    //
    // Clear Break CPU index value
    //
    mDebugMpContext.BreakAtCpuIndex = (UINT32)-1;
  }

  //
  // Get original IDT address and size.
  //
  AsmReadIdtr ((IA32_DESCRIPTOR *)&Idtr);
  IdtEntryCount = (UINT16)((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR));
  if (IdtEntryCount < 33) {
    ZeroMem (&mIdtEntryTable, sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33);
    //
    // Copy original IDT table into new one
    //
    CopyMem (&mIdtEntryTable, (VOID *)Idtr.Base, Idtr.Limit + 1);
    //
    // Load new IDT table
    //
    Idtr.Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1);
    Idtr.Base  = (UINTN)&mIdtEntryTable;
    AsmWriteIdtr ((IA32_DESCRIPTOR *)&Idtr);
  }

  //
  // Initialize the IDT table entries to support source level debug.
  //
  InitializeDebugIdt ();

  //
  // If mMailboxPointer is not set before, set it
  //
  if (mMailboxPointer == NULL) {
    if (Mailbox != NULL) {
      //
      // If Mailbox exists, copy it into one global variable
      //
      CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
    } else {
      ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX));
    }

    mMailboxPointer = &mMailbox;
  }

  //
  // Initialize Debug Timer hardware and save its initial count and frequency
  //
  mDebugMpContext.DebugTimerInitCount = InitializeDebugTimer (&DebugTimerFrequency, TRUE);
  UpdateMailboxContent (mMailboxPointer, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);
  //
  // Initialize debug communication port
  //
  DebugPortHandle = (UINT64)(UINTN)DebugPortInitialize ((VOID *)(UINTN)mMailboxPointer->DebugPortHandle, NULL);
  UpdateMailboxContent (mMailboxPointer, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);

  if (Mailbox == NULL) {
    //
    // Trigger one software interrupt to inform HOST
    //
    TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);
    SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
    //
    // Memory has been ready
    //
    if (IsHostAttached ()) {
      //
      // Trigger one software interrupt to inform HOST
      //
      TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
    }
  }
}

/**
  Initialize debug agent.

  This function is used to set up debug environment for DXE phase.

  If this function is called by DXE Core, Context must be the pointer
  to HOB list which will be used to get GUIDed HOB. It will enable
  interrupt to support break-in feature.
  If this function is called by DXE module, Context must be NULL. It
  will enable interrupt to support break-in feature.

  @param[in] InitFlag     Init flag is used to decide initialize process.
  @param[in] Context      Context needed according to InitFlag.
  @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
  )
{
  UINT64               *MailboxLocation;
  DEBUG_AGENT_MAILBOX  *Mailbox;
  BOOLEAN              InterruptStatus;
  VOID                 *HobList;
  IA32_DESCRIPTOR      IdtDescriptor;
  IA32_DESCRIPTOR      *Ia32Idtr;
  IA32_IDT_ENTRY       *Ia32IdtEntry;
  BOOLEAN              PeriodicMode;
  UINTN                TimerCycle;

  if (InitFlag == DEBUG_AGENT_INIT_DXE_AP) {
    //
    // Check if CPU APIC Timer is working, otherwise initialize it.
    //
    InitializeLocalApicSoftwareEnable (TRUE);
    GetApicTimerState (NULL, &PeriodicMode, NULL);
    TimerCycle = GetApicTimerInitCount ();
    if (!PeriodicMode || (TimerCycle == 0)) {
      InitializeDebugTimer (NULL, FALSE);
    }

    //
    // Invoked by AP, enable interrupt to let AP could receive IPI from other processors
    //
    EnableInterrupts ();
    return;
  }

  //
  // Disable Debug Timer interrupt
  //
  SaveAndSetDebugTimerInterrupt (FALSE);
  //
  // Save and disable original interrupt status
  //
  InterruptStatus = SaveAndDisableInterrupts ();

  //
  // Try to get mailbox firstly
  //
  HobList         = NULL;
  Mailbox         = NULL;
  MailboxLocation = NULL;

  switch (InitFlag) {
    case DEBUG_AGENT_INIT_DXE_LOAD:
      //
      // Check if Debug Agent has been initialized before
      //
      if (IsDebugAgentInitialzed ()) {
        DEBUG ((DEBUG_INFO, "Debug Agent: The former agent will be overwritten by the new one!\n"));
      }

      mMultiProcessorDebugSupport = TRUE;
      //
      // Save original IDT table
      //
      AsmReadIdtr (&IdtDescriptor);
      mSaveIdtTableSize = IdtDescriptor.Limit + 1;
      mSavedIdtTable    = AllocateCopyPool (mSaveIdtTableSize, (VOID *)IdtDescriptor.Base);
      //
      // Check if Debug Agent initialized in DXE phase
      //
      Mailbox = GetMailboxFromConfigurationTable ();
      if (Mailbox == NULL) {
        //
        // Try to get mailbox from GUIDed HOB build in PEI
        //
        HobList = GetHobList ();
        Mailbox = GetMailboxFromHob (HobList);
      }

      //
      // Set up Debug Agent Environment and try to connect HOST if required
      //
      SetupDebugAgentEnvironment (Mailbox);
      //
      // For DEBUG_AGENT_INIT_S3, needn't to install configuration table and EFI Serial IO protocol
      // For DEBUG_AGENT_INIT_DXE_CORE, InternalConstructorWorker() will invoked in Constructor()
      //
      InternalConstructorWorker ();
      //
      // Enable Debug Timer interrupt
      //
      SaveAndSetDebugTimerInterrupt (TRUE);
      //
      // Enable interrupt to receive Debug Timer interrupt
      //
      EnableInterrupts ();

      mDebugAgentInitialized = TRUE;
      FindAndReportModuleImageInfo (SIZE_4KB);

      *(EFI_STATUS *)Context = EFI_SUCCESS;

      break;

    case DEBUG_AGENT_INIT_DXE_UNLOAD:
      if (mDebugAgentInitialized) {
        if (IsHostAttached ()) {
          *(EFI_STATUS *)Context = EFI_ACCESS_DENIED;
          //
          // Enable Debug Timer interrupt again
          //
          SaveAndSetDebugTimerInterrupt (TRUE);
        } else {
          //
          // Restore original IDT table
          //
          AsmReadIdtr (&IdtDescriptor);
          IdtDescriptor.Limit = (UINT16)(mSaveIdtTableSize - 1);
          CopyMem ((VOID *)IdtDescriptor.Base, mSavedIdtTable, mSaveIdtTableSize);
          AsmWriteIdtr (&IdtDescriptor);
          FreePool (mSavedIdtTable);
          mDebugAgentInitialized = FALSE;
          *(EFI_STATUS *)Context = EFI_SUCCESS;
        }
      } else {
        *(EFI_STATUS *)Context = EFI_NOT_STARTED;
      }

      //
      // Restore interrupt state.
      //
      SetInterruptState (InterruptStatus);
      break;

    case DEBUG_AGENT_INIT_DXE_CORE:
      mDxeCoreFlag                = TRUE;
      mMultiProcessorDebugSupport = TRUE;
      //
      // Try to get mailbox from GUIDed HOB build in PEI
      //
      HobList = Context;
      Mailbox = GetMailboxFromHob (HobList);
      //
      // Set up Debug Agent Environment and try to connect HOST if required
      //
      SetupDebugAgentEnvironment (Mailbox);
      //
      // Enable Debug Timer interrupt
      //
      SaveAndSetDebugTimerInterrupt (TRUE);
      //
      // Enable interrupt to receive Debug Timer interrupt
      //
      EnableInterrupts ();

      break;

    case DEBUG_AGENT_INIT_S3:

      if (Context != NULL) {
        Ia32Idtr        =  (IA32_DESCRIPTOR *)Context;
        Ia32IdtEntry    = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
        MailboxLocation = (UINT64 *)((UINTN)Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +
                                     ((UINTN)Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));
        Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
        VerifyMailboxChecksum (Mailbox);
      }

      //
      // Save Mailbox pointer in global variable
      //
      mMailboxPointer = Mailbox;
      //
      // Set up Debug Agent Environment and try to connect HOST if required
      //
      SetupDebugAgentEnvironment (Mailbox);
      //
      // Disable interrupt
      //
      DisableInterrupts ();
      FindAndReportModuleImageInfo (SIZE_4KB);
      if (GetDebugFlag (DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT) == 1) {
        //
        // If Boot Script entry break is set, code will be break at here.
        //
        CpuBreakpoint ();
      }

      break;

    case DEBUG_AGENT_INIT_REINITIALIZE:
    case DEBUG_AGENT_INIT_DXE_CORE_LATE:

      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;
  }
}
