Ejemplo n.º 1
0
/**
  This is the main worker function that manages the state of the interrupt
  handlers.  It both installs and uninstalls interrupt handlers based on the
  value of NewCallback.  If NewCallback is NULL, then uninstall is indicated.
  If NewCallback is non-NULL, then install is indicated.

  @param  NewCallback   If non-NULL, NewCallback specifies the new handler to register.
                        If NULL, specifies that the previously registered handler should
                        be uninstalled.
  @param  ExceptionType Indicates which entry to manage.

  @retval EFI_SUCCESS            Installing or Uninstalling operation is ok.
  @retval EFI_INVALID_PARAMETER  Requested uninstalling a handler from a vector that has
                                 no handler registered for it
  @retval EFI_ALREADY_STARTED    Requested install to a vector that already has a handler registered.

**/
EFI_STATUS
ManageIdtEntryTable (
  CALLBACK_FUNC      NewCallback,
  EFI_EXCEPTION_TYPE ExceptionType
  )
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;

  if (CompareMem (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc, sizeof (IA32_IDT_GATE_DESCRIPTOR)) != 0) {
    //
    // we've already installed to this vector
    //
    if (NewCallback != NULL) {
      //
      // if the input handler is non-null, error
      //
      Status = EFI_ALREADY_STARTED;
    } else {
      UnhookEntry (ExceptionType);
    }
  } else {
    //
    // no user handler installed on this vector
    //
    if (NewCallback == NULL) {
      //
      // if the input handler is null, error
      //
      Status = EFI_INVALID_PARAMETER;
    } else {
      HookEntry (ExceptionType, NewCallback);
    }
  }

  return Status;
}
Ejemplo n.º 2
0
/**
  This is the worker function that uninstalls and removes all handlers.

  @param  ExceptionType     Specifies which processor exception.
  @param  NewBundles        New Boundles.
  @param  NewCallback       A pointer to the new function to be registered.

  @retval EFI_ALEADY_STARTED Ivt already hooked.
  @retval EFI_SUCCESS        Successfully uninstalled.

**/
EFI_STATUS
ManageIvtEntryTable (
  IN  EFI_EXCEPTION_TYPE           ExceptionType,
  IN  BUNDLE                       NewBundles[NUM_BUNDLES_IN_STUB],
  IN  CALLBACK_FUNC                NewCallback
  )
{
  BUNDLE  *B0Ptr;
  UINT64  InterruptFlags;
  EFI_TPL OldTpl;

  //
  // Get address of bundle 0
  //
  GetHandlerEntryPoint (ExceptionType, (VOID **) &B0Ptr);

  if (IvtEntryTable[ExceptionType].RegisteredCallback != NULL) {
    //
    // we've already installed to this vector
    //
    if (NewCallback != NULL) {
      //
      // if the input handler is non-null, error
      //
      return EFI_ALREADY_STARTED;
    } else {
      //
      // else remove the previously installed handler
      //
      OldTpl          = gBS->RaiseTPL (TPL_HIGH_LEVEL);
      InterruptFlags  = ProgramInterruptFlags (DISABLE_INTERRUPTS);
      if (ExceptionType == EXCEPT_IPF_EXTERNAL_INTERRUPT) {
        UnchainExternalInterrupt ();
      } else {
        UnhookEntry (ExceptionType);
      }

      ProgramInterruptFlags (InterruptFlags);
      gBS->RestoreTPL (OldTpl);
      //
      // re-init IvtEntryTable
      //
      ZeroMem (&IvtEntryTable[ExceptionType], sizeof (IVT_ENTRY));
    }
  } else {
    //
    // no user handler installed on this vector
    //
    if (NewCallback != NULL) {
      OldTpl          = gBS->RaiseTPL (TPL_HIGH_LEVEL);
      InterruptFlags  = ProgramInterruptFlags (DISABLE_INTERRUPTS);
      if (ExceptionType == EXCEPT_IPF_EXTERNAL_INTERRUPT) {
        ChainExternalInterrupt (NewCallback);
      } else {
        HookEntry (ExceptionType, NewBundles, NewCallback);
      }

      ProgramInterruptFlags (InterruptFlags);
      gBS->RestoreTPL (OldTpl);
    }
  }

  return EFI_SUCCESS;
}