/** @file
  Debug Agent library implementition for Dxe Core and Dxr modules.

  Copyright (c) 2010, 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;

IA32_IDT_GATE_DESCRIPTOR     mIdtEntryTable[33];

BOOLEAN                      mConfigurationTableNeeded = FALSE;

CONST BOOLEAN                MultiProcessorDebugSupport = TRUE;

/**
  Constructor allocates the NVS memory to store Mailbox and install configuration table
  in system table to store its pointer.

  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.
  @param[in]  SystemTable   A pointer to the EFI System Table.

  @retval  RETURN_SUCCESS            Allocate the global memory space to store guid and function tables.
  @retval  RETURN_OUT_OF_RESOURCES   No enough memory to allocated.

**/
RETURN_STATUS
EFIAPI
DxeDebugAgentLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                  Status;
  EFI_PHYSICAL_ADDRESS        Address;

  if (!mConfigurationTableNeeded) {
    return RETURN_SUCCESS;
  }

  Address = 0;
  Status = gBS->AllocatePages (
                  AllocateAnyPages,
                  EfiACPIMemoryNVS,
                  EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX)),
                  &Address
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  CopyMem (
    (UINT8 *) (UINTN) Address,
    (UINT8 *) (UINTN) mMailboxPointer,
    sizeof (DEBUG_AGENT_MAILBOX)
    );

  mMailboxPointer = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;

  return gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer);
}

/**
  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;

  GuidHob = GetNextGuidHob (&gEfiDebugAgentGuid, HobStart);
  if (GuidHob == NULL) {
    return NULL;
  }

  return (DEBUG_AGENT_MAILBOX *) (GET_GUID_HOB_DATA(GuidHob));
}

/**
  Get Debug Agent Mailbox pointer.

  @return Mailbox pointer.

**/
DEBUG_AGENT_MAILBOX *
GetMailboxPointer (
  VOID
  )
{
  return mMailboxPointer;
}

/**
  Get debug port handle.

  @return Debug port handle.

**/
DEBUG_PORT_HANDLE
GetDebugPortHandle (
  VOID
  )
{
  return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle);
}

 
/**
  Initialize debug agent.

  This function is used to set up debug enviroment 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
  )
{
  DEBUG_AGENT_MAILBOX          *Mailbox;
  IA32_DESCRIPTOR              Idtr;
  UINT16                       IdtEntryCount;
  BOOLEAN                      InterruptStatus;

  if (InitFlag != DEBUG_AGENT_INIT_DXE_CORE &&
      InitFlag != DEBUG_AGENT_INIT_S3 &&
      InitFlag != DEBUG_AGENT_INIT_DXE_AP) {
    return;
  }

  //
  // Save and disable original interrupt status
  //
  InterruptStatus = SaveAndDisableInterrupts ();

  if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {
    //
    // Try to get Mailbox from GUIDed HOB.
    //
    mConfigurationTableNeeded = TRUE;
    Mailbox = GetMailboxFromHob (Context);

  } else if (InitFlag == DEBUG_AGENT_INIT_DXE_AP) {

    EnableInterrupts ();

    return;

  } else {
    //
    // If it is in S3 path, needn't to install configuration table.
    //
    Mailbox = NULL;
  }

  if (Mailbox != NULL) {
    //
    // If Mailbox exists, copy it into one global variable.
    //
    CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
    mMailbox.DebugPortHandle = 0;
  } else {
    //
    // If Mailbox not exists, used the local Mailbox.
    //
    ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX));
  }

  mMailboxPointer = &mMailbox;

  //
  // Get original IDT address and size.
  //
  AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr);
  IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR));
  if (IdtEntryCount < 33) {
    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 ();

  //
  // Initialize debug communication port
  //
  mMailboxPointer->DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize (NULL, NULL);

  InitializeSpinLock (&mDebugMpContext.MpContextSpinLock);
  InitializeSpinLock (&mDebugMpContext.DebugPortSpinLock);
 
  if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {
    //
    // Initialize Debug Timer hardware and enable interrupt.
    //
    InitializeDebugTimer ();
    EnableInterrupts ();

    return;
  } else {
    //
    // Disable Debug Timer interrupt in S3 path.
    //
    SaveAndSetDebugTimerInterrupt (FALSE);

    //
    // Restore interrupt state.
    //
    SetInterruptState (InterruptStatus);
  }

}

