Пример #1
0
/**
  Called by the platform code to process a tick.

  @param  Duration               The number of 100ns elasped since the last call
                                 to TimerTick

**/
VOID
EFIAPI
CoreTimerTick (
  IN UINT64   Duration
  )
{
  IEVENT          *Event;

  //
  // Check runtiem flag in case there are ticks while exiting boot services
  //
  CoreAcquireLock (&mEfiSystemTimeLock);

  //
  // Update the system time
  //
  mEfiSystemTime += Duration;

  //
  // If the head of the list is expired, fire the timer event
  // to process it
  //
  if (!IsListEmpty (&mEfiTimerList)) {
    Event = CR (mEfiTimerList.ForwardLink, IEVENT, Timer.Link, EVENT_SIGNATURE);

    if (Event->Timer.TriggerTime <= mEfiSystemTime) {
      CoreSignalEvent (mEfiCheckTimerEvent);
    }
  }

  CoreReleaseLock (&mEfiSystemTimeLock);
}
Пример #2
0
VOID
CoreNotifyProtocolEntry (
  IN PROTOCOL_ENTRY   *ProtEntry
  )
/*++

Routine Description:

  Signal event for every protocol in protocol entry.

Arguments:

  ProtEntry     - Protocol entry

Returns:

--*/
{
  PROTOCOL_NOTIFY     *ProtNotify;
  EFI_LIST_ENTRY      *Link;

  ASSERT_LOCKED (&gProtocolDatabaseLock);

  for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
    ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
    CoreSignalEvent (ProtNotify->Event);
  }
}
Пример #3
0
/**
  Sets the type of timer and the trigger time for a timer event.

  @param  UserEvent              The timer event that is to be signaled at the
                                 specified time
  @param  Type                   The type of time that is specified in
                                 TriggerTime
  @param  TriggerTime            The number of 100ns units until the timer
                                 expires

  @retval EFI_SUCCESS            The event has been set to be signaled at the
                                 requested time
  @retval EFI_INVALID_PARAMETER  Event or Type is not valid

**/
EFI_STATUS
EFIAPI
CoreSetTimer (
  IN EFI_EVENT            UserEvent,
  IN EFI_TIMER_DELAY      Type,
  IN UINT64               TriggerTime
  )
{
  IEVENT      *Event;

  Event = UserEvent;

  if (Event == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Event->Signature != EVENT_SIGNATURE) {
    return EFI_INVALID_PARAMETER;
  }

  if ((UINT32)Type > TimerRelative  || (Event->Type & EVT_TIMER) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  CoreAcquireLock (&mEfiTimerLock);

  //
  // If the timer is queued to the timer database, remove it
  //
  if (Event->Timer.Link.ForwardLink != NULL) {
    RemoveEntryList (&Event->Timer.Link);
    Event->Timer.Link.ForwardLink = NULL;
  }

  Event->Timer.TriggerTime = 0;
  Event->Timer.Period = 0;

  if (Type != TimerCancel) {

    if (Type == TimerPeriodic) {
      if (TriggerTime == 0) {
        gTimer->GetTimerPeriod (gTimer, &TriggerTime);
      }
      Event->Timer.Period = TriggerTime;
    }

    Event->Timer.TriggerTime = CoreCurrentSystemTime () + TriggerTime;
    CoreInsertEventTimer (Event);

    if (TriggerTime == 0) {
      CoreSignalEvent (mEfiCheckTimerEvent);
    }
  }

  CoreReleaseLock (&mEfiTimerLock);

  return EFI_SUCCESS;
}
Пример #4
0
/**
  Signal event for every protocol in protocol entry.

  @param  ProtEntry              Protocol entry

**/
VOID
CoreNotifyProtocolEntry (
  IN PROTOCOL_ENTRY   *ProtEntry
  )
{
  PROTOCOL_NOTIFY     *ProtNotify;
  LIST_ENTRY          *Link;

  ASSERT_LOCKED (&gProtocolDatabaseLock);

  for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
    ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
    CoreSignalEvent (ProtNotify->Event);
  }
}
Пример #5
0
/**
  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;
  }

  for(;;) {

    for(Index = 0; Index < NumberOfEvents; Index++) {

      Status = CoreCheckEvent (UserEvents[Index]);

      //
      // provide index of event that caused problem
      //
      if (Status != EFI_NOT_READY) {
        *UserIndex = Index;
        return Status;
      }
    }

    //
    // Signal the Idle event
    //
    CoreSignalEvent (gIdleLoopEvent);
  }
}
Пример #6
0
/**
  Checks the sorted timer list against the current system time.
  Signals any expired event timer.

  @param  CheckEvent             Not used
  @param  Context                Not used

**/
VOID
EFIAPI
CoreCheckTimers (
  IN EFI_EVENT            CheckEvent,
  IN VOID                 *Context
  )
{
  UINT64                  SystemTime;
  IEVENT                  *Event;

  //
  // Check the timer database for expired timers
  //
  CoreAcquireLock (&mEfiTimerLock);
  SystemTime = CoreCurrentSystemTime ();

  while (!IsListEmpty (&mEfiTimerList)) {
    Event = CR (mEfiTimerList.ForwardLink, IEVENT, Timer.Link, EVENT_SIGNATURE);

    //
    // If this timer is not expired, then we're done
    //
    if (Event->Timer.TriggerTime > SystemTime) {
      break;
    }

    //
    // Remove this timer from the timer queue
    //

    RemoveEntryList (&Event->Timer.Link);
    Event->Timer.Link.ForwardLink = NULL;

    //
    // Signal it
    //
    CoreSignalEvent (Event);

    //
    // If this is a periodic timer, set it
    //
    if (Event->Timer.Period != 0) {
      //
      // Compute the timers new trigger time
      //
      Event->Timer.TriggerTime = Event->Timer.TriggerTime + Event->Timer.Period;

      //
      // If that's before now, then reset the timer to start from now
      //
      if (Event->Timer.TriggerTime <= SystemTime) {
        Event->Timer.TriggerTime = SystemTime;
        CoreSignalEvent (mEfiCheckTimerEvent);
      }

      //
      // Add the timer
      //
      CoreInsertEventTimer (Event);
    }
  }

  CoreReleaseLock (&mEfiTimerLock);
}