/** @file
  IA32/x64 generic functions to support Debug Support protocol.

Copyright (c) 2006 - 2009, Intel Corporation
All rights reserved. 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 "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 VOID                         (EFIAPI *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 (
  EFI_EXCEPTION_TYPE      ExceptionType,
  EFI_SYSTEM_CONTEXT_IA32 *ContextRecord
  )
{
  if (IdtEntryTable[ExceptionType].RegisteredCallback != NULL) {
    if (ExceptionType != SYSTEM_TIMER_VECTOR) {
      IdtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, ContextRecord);
    } else {
      OrigVector = IdtEntryTable[ExceptionType].OrigVector;
      IdtEntryTable[ExceptionType].RegisteredCallback (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;
}
