/** 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); }
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); } }
/** 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; }
/** 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); } }
/** 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); } }
/** 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); }