/** @file
  UEFI Event support functions implemented in this file.

Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DxeMain.h"
#include "Event.h"

///
/// gEfiCurrentTpl - Current Task priority level
///
EFI_TPL  gEfiCurrentTpl = TPL_APPLICATION;

///
/// gEventQueueLock - Protects the event queues
///
EFI_LOCK  gEventQueueLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);

///
/// gEventQueue - A list of event's to notify for each priority level
///
LIST_ENTRY  gEventQueue[TPL_HIGH_LEVEL + 1];

///
/// gEventPending - A bitmask of the EventQueues that are pending
///
UINTN  gEventPending = 0;

///
/// gEventSignalQueue - A list of events to signal based on EventGroup type
///
LIST_ENTRY  gEventSignalQueue = INITIALIZE_LIST_HEAD_VARIABLE (gEventSignalQueue);

///
/// Enumerate the valid types
///
UINT32  mEventTable[] = {
  ///
  /// 0x80000200       Timer event with a notification function that is
  /// queue when the event is signaled with SignalEvent()
  ///
  EVT_TIMER | EVT_NOTIFY_SIGNAL,
  ///
  /// 0x80000000       Timer event without a notification function. It can be
  /// signaled with SignalEvent() and checked with CheckEvent() or WaitForEvent().
  ///
  EVT_TIMER,
  ///
  /// 0x00000100       Generic event with a notification function that
  /// can be waited on with CheckEvent() or WaitForEvent()
  ///
  EVT_NOTIFY_WAIT,
  ///
  /// 0x00000200       Generic event with a notification function that
  /// is queue when the event is signaled with SignalEvent()
  ///
  EVT_NOTIFY_SIGNAL,
  ///
  /// 0x00000201       ExitBootServicesEvent.
  ///
  EVT_SIGNAL_EXIT_BOOT_SERVICES,
  ///
  /// 0x60000202       SetVirtualAddressMapEvent.
  ///
  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,

  ///
  /// 0x00000000       Generic event without a notification function.
  /// It can be signaled with SignalEvent() and checked with CheckEvent()
  /// or WaitForEvent().
  ///
  0x00000000,
  ///
  /// 0x80000100       Timer event with a notification function that can be
  /// waited on with CheckEvent() or WaitForEvent()
  ///
  EVT_TIMER | EVT_NOTIFY_WAIT,
};

///
/// gIdleLoopEvent - Event which is signalled when the core is idle
///
EFI_EVENT  gIdleLoopEvent = NULL;

/**
  Enter critical section by acquiring the lock on gEventQueueLock.

**/
VOID
CoreAcquireEventLock (
  VOID
  )
{
  CoreAcquireLock (&gEventQueueLock);
}

/**
  Exit critical section by releasing the lock on gEventQueueLock.

**/
VOID
CoreReleaseEventLock (
  VOID
  )
{
  CoreReleaseLock (&gEventQueueLock);
}

/**
  Initializes "event" support.

  @retval EFI_SUCCESS            Always return success

**/
EFI_STATUS
CoreInitializeEventServices (
  VOID
  )
{
  UINTN  Index;

  for (Index = 0; Index <= TPL_HIGH_LEVEL; Index++) {
    InitializeListHead (&gEventQueue[Index]);
  }

  CoreInitializeTimer ();

  CoreCreateEventEx (
    EVT_NOTIFY_SIGNAL,
    TPL_NOTIFY,
    EfiEventEmptyFunction,
    NULL,
    &gIdleLoopEventGuid,
    &gIdleLoopEvent
    );

  return EFI_SUCCESS;
}

/**
  Dispatches all pending events.

  @param  Priority               The task priority level of event notifications
                                 to dispatch

**/
VOID
CoreDispatchEventNotifies (
  IN EFI_TPL  Priority
  )
{
  IEVENT      *Event;
  LIST_ENTRY  *Head;

  CoreAcquireEventLock ();
  ASSERT (gEventQueueLock.OwnerTpl == Priority);
  Head = &gEventQueue[Priority];

  //
  // Dispatch all the pending notifications
  //
  while (!IsListEmpty (Head)) {
    Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);
    RemoveEntryList (&Event->NotifyLink);

    Event->NotifyLink.ForwardLink = NULL;

    //
    // Only clear the SIGNAL status if it is a SIGNAL type event.
    // WAIT type events are only cleared in CheckEvent()
    //
    if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {
      Event->SignalCount = 0;
    }

    CoreReleaseEventLock ();

    //
    // Notify this event
    //
    ASSERT (Event->NotifyFunction != NULL);
    Event->NotifyFunction (Event, Event->NotifyContext);

    //
    // Check for next pending event
    //
    CoreAcquireEventLock ();
  }

  gEventPending &= ~(UINTN)(1 << Priority);
  CoreReleaseEventLock ();
}

/**
  Queues the event's notification function to fire.

  @param  Event                  The Event to notify

**/
VOID
CoreNotifyEvent (
  IN  IEVENT  *Event
  )
{
  //
  // Event database must be locked
  //
  ASSERT_LOCKED (&gEventQueueLock);

  //
  // If the event is queued somewhere, remove it
  //

  if (Event->NotifyLink.ForwardLink != NULL) {
    RemoveEntryList (&Event->NotifyLink);
    Event->NotifyLink.ForwardLink = NULL;
  }

  //
  // Queue the event to the pending notification list
  //

  InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);
  gEventPending |= (UINTN)(1 << Event->NotifyTpl);
}

/**
  Signals all events in the EventGroup.

  @param  EventGroup             The list to signal

**/
VOID
CoreNotifySignalList (
  IN EFI_GUID  *EventGroup
  )
{
  LIST_ENTRY  *Link;
  LIST_ENTRY  *Head;
  IEVENT      *Event;

  CoreAcquireEventLock ();

  Head = &gEventSignalQueue;
  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
    Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);
    if (CompareGuid (&Event->EventGroup, EventGroup)) {
      CoreNotifyEvent (Event);
    }
  }

  CoreReleaseEventLock ();
}

/**
  Creates an event.

  @param  Type                   The type of event to create and its mode and
                                 attributes
  @param  NotifyTpl              The task priority level of event notifications
  @param  NotifyFunction         Pointer to the events notification function
  @param  NotifyContext          Pointer to the notification functions context;
                                 corresponds to parameter "Context" in the
                                 notification function
  @param  Event                  Pointer to the newly created event if the call
                                 succeeds; undefined otherwise

  @retval EFI_SUCCESS            The event structure was created
  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value
  @retval EFI_OUT_OF_RESOURCES   The event could not be allocated

**/
EFI_STATUS
EFIAPI
CoreCreateEvent (
  IN UINT32            Type,
  IN EFI_TPL           NotifyTpl,
  IN EFI_EVENT_NOTIFY  NotifyFunction  OPTIONAL,
  IN VOID              *NotifyContext  OPTIONAL,
  OUT EFI_EVENT        *Event
  )
{
  return CoreCreateEventEx (Type, NotifyTpl, NotifyFunction, NotifyContext, NULL, Event);
}

/**
  Creates an event in a group.

  @param  Type                   The type of event to create and its mode and
                                 attributes
  @param  NotifyTpl              The task priority level of event notifications
  @param  NotifyFunction         Pointer to the events notification function
  @param  NotifyContext          Pointer to the notification functions context;
                                 corresponds to parameter "Context" in the
                                 notification function
  @param  EventGroup             GUID for EventGroup if NULL act the same as
                                 gBS->CreateEvent().
  @param  Event                  Pointer to the newly created event if the call
                                 succeeds; undefined otherwise

  @retval EFI_SUCCESS            The event structure was created
  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value
  @retval EFI_OUT_OF_RESOURCES   The event could not be allocated

**/
EFI_STATUS
EFIAPI
CoreCreateEventEx (
  IN UINT32            Type,
  IN EFI_TPL           NotifyTpl,
  IN EFI_EVENT_NOTIFY  NotifyFunction  OPTIONAL,
  IN CONST VOID        *NotifyContext  OPTIONAL,
  IN CONST EFI_GUID    *EventGroup     OPTIONAL,
  OUT EFI_EVENT        *Event
  )
{
  //
  // If it's a notify type of event, check for invalid NotifyTpl
  //
  if ((Type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL)) != 0) {
    if ((NotifyTpl != TPL_APPLICATION) &&
        (NotifyTpl != TPL_CALLBACK) &&
        (NotifyTpl != TPL_NOTIFY))
    {
      return EFI_INVALID_PARAMETER;
    }
  }

  return CoreCreateEventInternal (Type, NotifyTpl, NotifyFunction, NotifyContext, EventGroup, Event);
}

/**
  Creates a general-purpose event structure

  @param  Type                   The type of event to create and its mode and
                                 attributes
  @param  NotifyTpl              The task priority level of event notifications
  @param  NotifyFunction         Pointer to the events notification function
  @param  NotifyContext          Pointer to the notification functions context;
                                 corresponds to parameter "Context" in the
                                 notification function
  @param  EventGroup             GUID for EventGroup if NULL act the same as
                                 gBS->CreateEvent().
  @param  Event                  Pointer to the newly created event if the call
                                 succeeds; undefined otherwise

  @retval EFI_SUCCESS            The event structure was created
  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value
  @retval EFI_OUT_OF_RESOURCES   The event could not be allocated

**/
EFI_STATUS
EFIAPI
CoreCreateEventInternal (
  IN UINT32            Type,
  IN EFI_TPL           NotifyTpl,
  IN EFI_EVENT_NOTIFY  NotifyFunction  OPTIONAL,
  IN CONST VOID        *NotifyContext  OPTIONAL,
  IN CONST EFI_GUID    *EventGroup     OPTIONAL,
  OUT EFI_EVENT        *Event
  )
{
  EFI_STATUS  Status;
  IEVENT      *IEvent;
  INTN        Index;

  if (Event == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check to make sure no reserved flags are set
  //
  Status = EFI_INVALID_PARAMETER;
  for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) {
    if (Type == mEventTable[Index]) {
      Status = EFI_SUCCESS;
      break;
    }
  }

  if (EFI_ERROR (Status)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Convert Event type for pre-defined Event groups
  //
  if (EventGroup != NULL) {
    //
    // For event group, type EVT_SIGNAL_EXIT_BOOT_SERVICES and EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
    // are not valid
    //
    if ((Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) || (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE)) {
      return EFI_INVALID_PARAMETER;
    }

    if (CompareGuid (EventGroup, &gEfiEventExitBootServicesGuid)) {
      Type = EVT_SIGNAL_EXIT_BOOT_SERVICES;
    } else if (CompareGuid (EventGroup, &gEfiEventVirtualAddressChangeGuid)) {
      Type = EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE;
    }
  } else {
    //
    // Convert EFI 1.10 Events to their UEFI 2.0 CreateEventEx mapping
    //
    if (Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) {
      EventGroup = &gEfiEventExitBootServicesGuid;
    } else if (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {
      EventGroup = &gEfiEventVirtualAddressChangeGuid;
    }
  }

  //
  // If it's a notify type of event, check its parameters
  //
  if ((Type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL)) != 0) {
    //
    // Check for an invalid NotifyFunction or NotifyTpl
    //
    if ((NotifyFunction == NULL) ||
        (NotifyTpl <= TPL_APPLICATION) ||
        (NotifyTpl >= TPL_HIGH_LEVEL))
    {
      return EFI_INVALID_PARAMETER;
    }
  } else {
    //
    // No notification needed, zero ignored values
    //
    NotifyTpl      = 0;
    NotifyFunction = NULL;
    NotifyContext  = NULL;
  }

  //
  // Allocate and initialize a new event structure.
  //
  if ((Type & EVT_RUNTIME) != 0) {
    IEvent = AllocateRuntimeZeroPool (sizeof (IEVENT));
  } else {
    IEvent = AllocateZeroPool (sizeof (IEVENT));
  }

  if (IEvent == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  IEvent->Signature = EVENT_SIGNATURE;
  IEvent->Type      = Type;

  IEvent->NotifyTpl      = NotifyTpl;
  IEvent->NotifyFunction = NotifyFunction;
  IEvent->NotifyContext  = (VOID *)NotifyContext;
  if (EventGroup != NULL) {
    CopyGuid (&IEvent->EventGroup, EventGroup);
    IEvent->ExFlag |= EVT_EXFLAG_EVENT_GROUP;
  }

  *Event = IEvent;

  if ((Type & EVT_RUNTIME) != 0) {
    //
    // Keep a list of all RT events so we can tell the RT AP.
    //
    IEvent->RuntimeData.Type           = Type;
    IEvent->RuntimeData.NotifyTpl      = NotifyTpl;
    IEvent->RuntimeData.NotifyFunction = NotifyFunction;
    IEvent->RuntimeData.NotifyContext  = (VOID *)NotifyContext;
    //
    // Work around the bug in the Platform Init specification (v1.7), reported
    // as Mantis#2017: "EFI_RUNTIME_EVENT_ENTRY.Event" should have type
    // EFI_EVENT, not (EFI_EVENT*). The PI spec documents the field correctly
    // as "The EFI_EVENT returned by CreateEvent()", but the type of the field
    // doesn't match the natural language description. Therefore we need an
    // explicit cast here.
    //
    IEvent->RuntimeData.Event = (EFI_EVENT *)IEvent;
    InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link);
  }

  CoreAcquireEventLock ();

  if ((Type & EVT_NOTIFY_SIGNAL) != 0x00000000) {
    //
    // The Event's NotifyFunction must be queued whenever the event is signaled
    //
    InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink);
  }

  CoreReleaseEventLock ();

  //
  // Done
  //
  return EFI_SUCCESS;
}

/**
  Signals the event.  Queues the event to be notified if needed.

  @param  UserEvent              The event to signal .

  @retval EFI_INVALID_PARAMETER  Parameters are not valid.
  @retval EFI_SUCCESS            The event was signaled.

**/
EFI_STATUS
EFIAPI
CoreSignalEvent (
  IN EFI_EVENT  UserEvent
  )
{
  IEVENT  *Event;

  Event = UserEvent;

  if (Event == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Event->Signature != EVENT_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }

  CoreAcquireEventLock ();

  //
  // If the event is not already signalled, do so
  //

  if (Event->SignalCount == 0x00000000) {
    Event->SignalCount++;

    //
    // If signalling type is a notify function, queue it
    //
    if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {
      if ((Event->ExFlag & EVT_EXFLAG_EVENT_GROUP) != 0) {
        //
        // The CreateEventEx() style requires all members of the Event Group
        //  to be signaled.
        //
        CoreReleaseEventLock ();
        CoreNotifySignalList (&Event->EventGroup);
        CoreAcquireEventLock ();
      } else {
        CoreNotifyEvent (Event);
      }
    }
  }

  CoreReleaseEventLock ();
  return EFI_SUCCESS;
}

/**
  Check the status of an event.

  @param  UserEvent              The event to check

  @retval EFI_SUCCESS            The event is in the signaled state
  @retval EFI_NOT_READY          The event is not in the signaled state
  @retval EFI_INVALID_PARAMETER  Event is of type EVT_NOTIFY_SIGNAL

**/
EFI_STATUS
EFIAPI
CoreCheckEvent (
  IN EFI_EVENT  UserEvent
  )
{
  IEVENT      *Event;
  EFI_STATUS  Status;

  Event = UserEvent;

  if (Event == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Event->Signature != EVENT_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  Status = EFI_NOT_READY;

  if ((Event->SignalCount == 0) && ((Event->Type & EVT_NOTIFY_WAIT) != 0)) {
    //
    // Queue the wait notify function
    //
    CoreAcquireEventLock ();
    if (Event->SignalCount == 0) {
      CoreNotifyEvent (Event);
    }

    CoreReleaseEventLock ();
  }

  //
  // If the even looks signalled, get the lock and clear it
  //

  if (Event->SignalCount != 0) {
    CoreAcquireEventLock ();

    if (Event->SignalCount != 0) {
      Event->SignalCount = 0;
      Status             = EFI_SUCCESS;
    }

    CoreReleaseEventLock ();
  }

  return Status;
}

/**
  Stops execution until an event is signaled.

  @param  NumberOfEvents         The number of events in the UserEvents array
  @param  UserEvents             An array of EFI_EVENT
  @param  UserIndex              Pointer to the index of the event which
                                 satisfied the wait condition

  @retval EFI_SUCCESS            The event indicated by Index was signaled.
  @retval EFI_INVALID_PARAMETER  The event indicated by Index has a notification
                                 function or Event was not a valid type
  @retval EFI_UNSUPPORTED        The current TPL is not TPL_APPLICATION

**/
EFI_STATUS
EFIAPI
CoreWaitForEvent (
  IN UINTN      NumberOfEvents,
  IN EFI_EVENT  *UserEvents,
  OUT UINTN     *UserIndex
  )
{
  EFI_STATUS  Status;
  UINTN       Index;

  //
  // Can only WaitForEvent at TPL_APPLICATION
  //
  if (gEfiCurrentTpl != TPL_APPLICATION) {
    return EFI_UNSUPPORTED;
  }

  if (NumberOfEvents == 0) {
    return EFI_INVALID_PARAMETER;
  }

  if (UserEvents == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  for ( ; ;) {
    for (Index = 0; Index < NumberOfEvents; Index++) {
      Status = CoreCheckEvent (UserEvents[Index]);

      //
      // provide index of event that caused problem
      //
      if (Status != EFI_NOT_READY) {
        if (UserIndex != NULL) {
          *UserIndex = Index;
        }

        return Status;
      }
    }

    //
    // Signal the Idle event
    //
    CoreSignalEvent (gIdleLoopEvent);
  }
}

/**
  Closes an event and frees the event structure.

  @param  UserEvent              Event to close

  @retval EFI_INVALID_PARAMETER  Parameters are not valid.
  @retval EFI_SUCCESS            The event has been closed

**/
EFI_STATUS
EFIAPI
CoreCloseEvent (
  IN EFI_EVENT  UserEvent
  )
{
  EFI_STATUS  Status;
  IEVENT      *Event;

  Event = UserEvent;

  if (Event == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Event->Signature != EVENT_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // If it's a timer event, make sure it's not pending
  //
  if ((Event->Type & EVT_TIMER) != 0) {
    CoreSetTimer (Event, TimerCancel, 0);
  }

  CoreAcquireEventLock ();

  //
  // If the event is queued somewhere, remove it
  //

  if (Event->RuntimeData.Link.ForwardLink != NULL) {
    RemoveEntryList (&Event->RuntimeData.Link);
  }

  if (Event->NotifyLink.ForwardLink != NULL) {
    RemoveEntryList (&Event->NotifyLink);
  }

  if (Event->SignalLink.ForwardLink != NULL) {
    RemoveEntryList (&Event->SignalLink);
  }

  CoreReleaseEventLock ();

  //
  // If the event is registered on a protocol notify, then remove it from the protocol database
  //
  if ((Event->ExFlag & EVT_EXFLAG_EVENT_PROTOCOL_NOTIFICATION) != 0) {
    CoreUnregisterProtocolNotify (Event);
  }

  //
  // To avoid the Event to be signalled wrongly after closed,
  // clear the Signature of Event before free pool.
  //
  Event->Signature = 0;
  Status           = CoreFreePool (Event);
  ASSERT_EFI_ERROR (Status);

  return Status;
}
