4 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
16 LIST_ENTRY mEfiTimerList
= INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList
);
17 EFI_LOCK mEfiTimerLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL
- 1);
18 EFI_EVENT mEfiCheckTimerEvent
= NULL
;
20 EFI_LOCK mEfiSystemTimeLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL
);
21 UINT64 mEfiSystemTime
= 0;
28 Inserts the timer event.
30 @param Event Points to the internal structure of timer event
35 CoreInsertEventTimer (
43 ASSERT_LOCKED (&mEfiTimerLock
);
46 // Get the timer's trigger time
48 TriggerTime
= Event
->Timer
.TriggerTime
;
51 // Insert the timer into the timer database in assending sorted order
53 for (Link
= mEfiTimerList
.ForwardLink
; Link
!= &mEfiTimerList
; Link
= Link
->ForwardLink
) {
54 Event2
= CR (Link
, IEVENT
, Timer
.Link
, EVENT_SIGNATURE
);
56 if (Event2
->Timer
.TriggerTime
> TriggerTime
) {
61 InsertTailList (Link
, &Event
->Timer
.Link
);
65 Returns the current system time.
67 @return The current system time
71 CoreCurrentSystemTime (
77 CoreAcquireLock (&mEfiSystemTimeLock
);
78 SystemTime
= mEfiSystemTime
;
79 CoreReleaseLock (&mEfiSystemTimeLock
);
85 Checks the sorted timer list against the current system time.
86 Signals any expired event timer.
88 @param CheckEvent Not used
89 @param Context Not used
95 IN EFI_EVENT CheckEvent
,
103 // Check the timer database for expired timers
105 CoreAcquireLock (&mEfiTimerLock
);
106 SystemTime
= CoreCurrentSystemTime ();
108 while (!IsListEmpty (&mEfiTimerList
)) {
109 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, Timer
.Link
, EVENT_SIGNATURE
);
112 // If this timer is not expired, then we're done
114 if (Event
->Timer
.TriggerTime
> SystemTime
) {
119 // Remove this timer from the timer queue
122 RemoveEntryList (&Event
->Timer
.Link
);
123 Event
->Timer
.Link
.ForwardLink
= NULL
;
128 CoreSignalEvent (Event
);
131 // If this is a periodic timer, set it
133 if (Event
->Timer
.Period
!= 0) {
135 // Compute the timers new trigger time
137 Event
->Timer
.TriggerTime
= Event
->Timer
.TriggerTime
+ Event
->Timer
.Period
;
140 // If that's before now, then reset the timer to start from now
142 if (Event
->Timer
.TriggerTime
<= SystemTime
) {
143 Event
->Timer
.TriggerTime
= SystemTime
;
144 CoreSignalEvent (mEfiCheckTimerEvent
);
150 CoreInsertEventTimer (Event
);
154 CoreReleaseLock (&mEfiTimerLock
);
158 Initializes timer support.
162 CoreInitializeTimer (
168 Status
= CoreCreateEventInternal (
176 ASSERT_EFI_ERROR (Status
);
180 Called by the platform code to process a tick.
182 @param Duration The number of 100ns elapsed since the last call
195 // Check runtiem flag in case there are ticks while exiting boot services
197 CoreAcquireLock (&mEfiSystemTimeLock
);
200 // Update the system time
202 mEfiSystemTime
+= Duration
;
205 // If the head of the list is expired, fire the timer event
208 if (!IsListEmpty (&mEfiTimerList
)) {
209 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, Timer
.Link
, EVENT_SIGNATURE
);
211 if (Event
->Timer
.TriggerTime
<= mEfiSystemTime
) {
212 CoreSignalEvent (mEfiCheckTimerEvent
);
216 CoreReleaseLock (&mEfiSystemTimeLock
);
220 Sets the type of timer and the trigger time for a timer event.
222 @param UserEvent The timer event that is to be signaled at the
224 @param Type The type of time that is specified in
226 @param TriggerTime The number of 100ns units until the timer
229 @retval EFI_SUCCESS The event has been set to be signaled at the
231 @retval EFI_INVALID_PARAMETER Event or Type is not valid
237 IN EFI_EVENT UserEvent
,
238 IN EFI_TIMER_DELAY Type
,
239 IN UINT64 TriggerTime
247 return EFI_INVALID_PARAMETER
;
250 if (Event
->Signature
!= EVENT_SIGNATURE
) {
251 return EFI_INVALID_PARAMETER
;
254 if (((UINT32
)Type
> TimerRelative
) || ((Event
->Type
& EVT_TIMER
) == 0)) {
255 return EFI_INVALID_PARAMETER
;
258 CoreAcquireLock (&mEfiTimerLock
);
261 // If the timer is queued to the timer database, remove it
263 if (Event
->Timer
.Link
.ForwardLink
!= NULL
) {
264 RemoveEntryList (&Event
->Timer
.Link
);
265 Event
->Timer
.Link
.ForwardLink
= NULL
;
268 Event
->Timer
.TriggerTime
= 0;
269 Event
->Timer
.Period
= 0;
271 if (Type
!= TimerCancel
) {
272 if (Type
== TimerPeriodic
) {
273 if (TriggerTime
== 0) {
274 gTimer
->GetTimerPeriod (gTimer
, &TriggerTime
);
277 Event
->Timer
.Period
= TriggerTime
;
280 Event
->Timer
.TriggerTime
= CoreCurrentSystemTime () + TriggerTime
;
281 CoreInsertEventTimer (Event
);
283 if (TriggerTime
== 0) {
284 CoreSignalEvent (mEfiCheckTimerEvent
);
288 CoreReleaseLock (&mEfiTimerLock
);