/** @file
  Debug Agent library implementition for Dxe Core and Dxr modules.

  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 "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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));
    CpuDeadLoop ();
    break;
  }
}
