/** @file
  IA32/x64 generic functions to support Debug Support protocol.

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DebugSupport.h"

//
// This the global main table to keep track of the interrupts
//
IDT_ENTRY  *IdtEntryTable = NULL;

/**
  Read IDT Gate Descriptor from IDT Table.

  @param  Vector            Specifies vector number.
  @param  IdtGateDescriptor Pointer to IDT Gate Descriptor read from IDT Table.

**/
VOID
ReadIdtGateDescriptor (
  IN  EFI_EXCEPTION_TYPE        Vector,
  OUT IA32_IDT_GATE_DESCRIPTOR  *IdtGateDescriptor
  )
{
  IA32_DESCRIPTOR           IdtrValue;
  IA32_IDT_GATE_DESCRIPTOR  *IdtTable;

  AsmReadIdtr (&IdtrValue);
  IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtrValue.Base;

  CopyMem ((VOID *)IdtGateDescriptor, (VOID *)&(IdtTable)[Vector], sizeof (IA32_IDT_GATE_DESCRIPTOR));
}

/**
  Write IDT Gate Descriptor into IDT Table.

  @param  Vector            Specifies vector number.
  @param  IdtGateDescriptor Pointer to IDT Gate Descriptor written into IDT Table.

**/
VOID
WriteIdtGateDescriptor (
  EFI_EXCEPTION_TYPE        Vector,
  IA32_IDT_GATE_DESCRIPTOR  *IdtGateDescriptor
  )
{
  IA32_DESCRIPTOR           IdtrValue;
  IA32_IDT_GATE_DESCRIPTOR  *IdtTable;

  AsmReadIdtr (&IdtrValue);
  IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtrValue.Base;

  CopyMem ((VOID *)&(IdtTable)[Vector], (VOID *)IdtGateDescriptor, sizeof (IA32_IDT_GATE_DESCRIPTOR));
}

/**
  Creates a nes entry stub.  Then saves the current IDT entry and replaces it
  with an interrupt gate for the new entry point.  The IdtEntryTable is updated
  with the new registered function.

  This code executes in boot services context.  The stub entry executes in interrupt
  context.

  @param  ExceptionType      Specifies which vector to hook.
  @param  NewCallback        A pointer to the new function to be registered.

**/
VOID
HookEntry (
  IN EFI_EXCEPTION_TYPE  ExceptionType,
  IN CALLBACK_FUNC       NewCallback
  )
{
  BOOLEAN  OldIntFlagState;

  CreateEntryStub (ExceptionType, (VOID **)&IdtEntryTable[ExceptionType].StubEntry);

  //
  // Disables CPU interrupts and returns the previous interrupt state
  //
  OldIntFlagState = SaveAndDisableInterrupts ();

  //
  // gets IDT Gate descriptor by index
  //
  ReadIdtGateDescriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));
  //
  // stores orignal interrupt handle
  //
  IdtEntryTable[ExceptionType].OrigVector = (DEBUG_PROC)GetInterruptHandleFromIdt (&(IdtEntryTable[ExceptionType].OrigDesc));

  //
  // encodes new IDT Gate descriptor by stub entry
  //
  Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry);
  //
  // stores NewCallback
  //
  IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback;

  //
  // writes back new IDT Gate descriptor
  //
  WriteIdtGateDescriptor (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc));

  //
  // restore interrupt state
  //
  SetInterruptState (OldIntFlagState);

  return;
}

/**
  Undoes HookEntry. This code executes in boot services context.

  @param  ExceptionType   Specifies which entry to unhook

**/
VOID
UnhookEntry (
  IN EFI_EXCEPTION_TYPE  ExceptionType
  )
{
  BOOLEAN  OldIntFlagState;

  //
  // Disables CPU interrupts and returns the previous interrupt state
  //
  OldIntFlagState = SaveAndDisableInterrupts ();

  //
  // restore the default IDT Date Descriptor
  //
  WriteIdtGateDescriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));

  //
  // restore interrupt state
  //
  SetInterruptState (OldIntFlagState);

  return;
}

/**
  Returns the maximum value that may be used for the ProcessorIndex parameter in
  RegisterPeriodicCallback() and RegisterExceptionCallback().

  Hard coded to support only 1 processor for now.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance.
  @param  MaxProcessorIndex     Pointer to a caller-allocated UINTN in which the maximum supported
                                processor index is returned. Always 0 returned.

  @retval EFI_SUCCESS           Always returned with **MaxProcessorIndex set to 0.

**/
EFI_STATUS
EFIAPI
GetMaximumProcessorIndex (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  OUT UINTN                      *MaxProcessorIndex
  )
{
  *MaxProcessorIndex = 0;
  return EFI_SUCCESS;
}

/**
  Registers a function to be called back periodically in interrupt context.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance.
  @param  ProcessorIndex        Specifies which processor the callback function applies to.
  @param  PeriodicCallback      A pointer to a function of type PERIODIC_CALLBACK that is the main
                                periodic entry point of the debug agent.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_ALREADY_STARTED   Non-NULL PeriodicCallback parameter when a callback
                                function was previously registered.
  @retval EFI_OUT_OF_RESOURCES  System has insufficient memory resources to register new callback
                                function.
**/
EFI_STATUS
EFIAPI
RegisterPeriodicCallback (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  IN UINTN                       ProcessorIndex,
  IN EFI_PERIODIC_CALLBACK       PeriodicCallback
  )
{
  return ManageIdtEntryTable (PeriodicCallback, SYSTEM_TIMER_VECTOR);
}

/**
  Registers a function to be called when a given processor exception occurs.

  This code executes in boot services context.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance.
  @param  ProcessorIndex        Specifies which processor the callback function applies to.
  @param  ExceptionCallback     A pointer to a function of type EXCEPTION_CALLBACK that is called
                                when the processor exception specified by ExceptionType occurs.
  @param  ExceptionType         Specifies which processor exception to hook.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_ALREADY_STARTED   Non-NULL PeriodicCallback parameter when a callback
                                function was previously registered.
  @retval EFI_OUT_OF_RESOURCES  System has insufficient memory resources to register new callback
                                function.
**/
EFI_STATUS
EFIAPI
RegisterExceptionCallback (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  IN UINTN                       ProcessorIndex,
  IN EFI_EXCEPTION_CALLBACK      ExceptionCallback,
  IN EFI_EXCEPTION_TYPE          ExceptionType
  )
{
  return ManageIdtEntryTable (ExceptionCallback, ExceptionType);
}

/**
  Invalidates processor instruction cache for a memory range. Subsequent execution in this range
  causes a fresh memory fetch to retrieve code to be executed.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance.
  @param  ProcessorIndex        Specifies which processor's instruction cache is to be invalidated.
  @param  Start                 Specifies the physical base of the memory range to be invalidated.
  @param  Length                Specifies the minimum number of bytes in the processor's instruction
                                cache to invalidate.

  @retval EFI_SUCCESS           Always returned.

**/
EFI_STATUS
EFIAPI
InvalidateInstructionCache (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  IN UINTN                       ProcessorIndex,
  IN VOID                        *Start,
  IN UINT64                      Length
  )
{
  AsmWbinvd ();
  return EFI_SUCCESS;
}

/**
  Common piece of code that invokes the registered handlers.

  This code executes in exception context so no efi calls are allowed.
  This code is called from assembly file.

  @param  ExceptionType     Exception type
  @param  ContextRecord     System context

**/
VOID
InterruptDistrubutionHub (
  IN EFI_EXCEPTION_TYPE  ExceptionType,
  IN EFI_SYSTEM_CONTEXT  ContextRecord
  )
{
  EFI_EXCEPTION_CALLBACK  ExceptionCallback;
  EFI_PERIODIC_CALLBACK   PeriodicCallback;

  if (IdtEntryTable[ExceptionType].RegisteredCallback == NULL) {
    return;
  }

  if (ExceptionType == SYSTEM_TIMER_VECTOR) {
    OrigVector       = IdtEntryTable[ExceptionType].OrigVector;
    PeriodicCallback = (EFI_PERIODIC_CALLBACK)IdtEntryTable[ExceptionType].RegisteredCallback;
    PeriodicCallback (ContextRecord);
  } else {
    ExceptionCallback = (EFI_EXCEPTION_CALLBACK)IdtEntryTable[ExceptionType].RegisteredCallback;
    ExceptionCallback (ExceptionType, ContextRecord);
  }
}

/**
  This is the callback that is written to the Loaded Image protocol instance
  on the image handle. It uninstalls all registered handlers and frees all entry
  stub memory.

  @param  ImageHandle    The firmware allocated handle for the EFI image.

  @retval EFI_SUCCESS    Always.

**/
EFI_STATUS
EFIAPI
PlUnloadDebugSupportDriver (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_EXCEPTION_TYPE  ExceptionType;

  for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) {
    ManageIdtEntryTable (NULL, ExceptionType);
    //
    // Free space for each Interrupt Stub precedure.
    //
    if (IdtEntryTable[ExceptionType].StubEntry != NULL) {
      FreePool ((VOID *)(UINTN)IdtEntryTable[ExceptionType].StubEntry);
    }
  }

  FreePool (IdtEntryTable);

  return EFI_SUCCESS;
}

/**
  Initializes driver's handler registration database.

  This code executes in boot services context.
  Must be public because it's referenced from DebugSupport.c

  @retval  EFI_UNSUPPORTED      If IA32/x64 processor does not support FXSTOR/FXRSTOR instructions,
                                the context save will fail, so these processors are not supported.
  @retval  EFI_OUT_OF_RESOURCES Fails to allocate memory.
  @retval  EFI_SUCCESS          Initializes successfully.

**/
EFI_STATUS
PlInitializeDebugSupportDriver (
  VOID
  )
{
  EFI_EXCEPTION_TYPE  ExceptionType;

  //
  // Check whether FxStor instructions are supported.
  //
  if (!FxStorSupport ()) {
    return EFI_UNSUPPORTED;
  }

  IdtEntryTable = AllocateZeroPool (sizeof (IDT_ENTRY) * NUM_IDT_ENTRIES);
  if (IdtEntryTable == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) {
    IdtEntryTable[ExceptionType].StubEntry = (DEBUG_PROC)(UINTN)AllocatePool (StubSize);
    if (IdtEntryTable[ExceptionType].StubEntry == NULL) {
      goto ErrorCleanup;
    }

    //
    // Copy Interrupt stub code.
    //
    CopyMem ((VOID *)(UINTN)IdtEntryTable[ExceptionType].StubEntry, InterruptEntryStub, StubSize);
  }

  return EFI_SUCCESS;

ErrorCleanup:

  for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) {
    if (IdtEntryTable[ExceptionType].StubEntry != NULL) {
      FreePool ((VOID *)(UINTN)IdtEntryTable[ExceptionType].StubEntry);
    }
  }

  FreePool (IdtEntryTable);

  return EFI_OUT_OF_RESOURCES;
}
