/** @file
  Debug Agent library implementation for Dxe Core and Dxr modules.

  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<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;

    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;
  }
}
