5 Copyright (c) 2006 - 2008, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 // Internal prototypes
24 CoreCurrentSystemTime (
38 CoreInsertEventTimer (
46 static LIST_ENTRY mEfiTimerList
= INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList
);
47 static EFI_LOCK mEfiTimerLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL
- 1);
48 static EFI_EVENT mEfiCheckTimerEvent
;
50 static EFI_LOCK mEfiSystemTimeLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL
);
51 static UINT64 mEfiSystemTime
= 0;
65 Initializes timer support
79 Status
= CoreCreateEvent (
86 ASSERT_EFI_ERROR (Status
);
91 CoreCurrentSystemTime (
98 Returns the current system time
106 Returns the current system time
112 CoreAcquireLock (&mEfiSystemTimeLock
);
113 SystemTime
= mEfiSystemTime
;
114 CoreReleaseLock (&mEfiSystemTimeLock
);
127 Called by the platform code to process a tick.
131 Duration - The number of 100ns elasped since the last call to TimerTick
142 // Check runtiem flag in case there are ticks while exiting boot services
145 CoreAcquireLock (&mEfiSystemTimeLock
);
148 // Update the system time
151 mEfiSystemTime
+= Duration
;
154 // If the head of the list is expired, fire the timer event
158 if (!IsListEmpty (&mEfiTimerList
)) {
159 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
161 if (Event
->u
.Timer
.TriggerTime
<= mEfiSystemTime
) {
162 CoreSignalEvent (mEfiCheckTimerEvent
);
166 CoreReleaseLock (&mEfiSystemTimeLock
);
173 IN EFI_EVENT CheckEvent
,
180 Checks the sorted timer list against the current system time.
181 Signals any expired event timer.
185 CheckEvent - Not used
199 // Check the timer database for expired timers
202 CoreAcquireLock (&mEfiTimerLock
);
203 SystemTime
= CoreCurrentSystemTime ();
205 while (!IsListEmpty (&mEfiTimerList
)) {
206 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
209 // If this timer is not expired, then we're done
212 if (Event
->u
.Timer
.TriggerTime
> SystemTime
) {
217 // Remove this timer from the timer queue
220 RemoveEntryList (&Event
->u
.Timer
.Link
);
221 Event
->u
.Timer
.Link
.ForwardLink
= NULL
;
226 CoreSignalEvent (Event
);
229 // If this is a periodic timer, set it
231 if (Event
->u
.Timer
.Period
) {
234 // Compute the timers new trigger time
237 Event
->u
.Timer
.TriggerTime
= Event
->u
.Timer
.TriggerTime
+ Event
->u
.Timer
.Period
;
240 // If that's before now, then reset the timer to start from now
242 if (Event
->u
.Timer
.TriggerTime
<= SystemTime
) {
243 Event
->u
.Timer
.TriggerTime
= SystemTime
;
244 CoreSignalEvent (mEfiCheckTimerEvent
);
251 CoreInsertEventTimer (Event
);
255 CoreReleaseLock (&mEfiTimerLock
);
260 CoreInsertEventTimer (
267 Inserts the timer event
271 Event - Points to the internal structure of timer event to be installed
283 ASSERT_LOCKED (&mEfiTimerLock
);
286 // Get the timer's trigger time
289 TriggerTime
= Event
->u
.Timer
.TriggerTime
;
292 // Insert the timer into the timer database in assending sorted order
295 for (Link
= mEfiTimerList
.ForwardLink
; Link
!= &mEfiTimerList
; Link
= Link
->ForwardLink
) {
296 Event2
= CR (Link
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
298 if (Event2
->u
.Timer
.TriggerTime
> TriggerTime
) {
303 InsertTailList (Link
, &Event
->u
.Timer
.Link
);
311 IN EFI_EVENT UserEvent
,
312 IN EFI_TIMER_DELAY Type
,
313 IN UINT64 TriggerTime
319 Sets the type of timer and the trigger time for a timer event.
323 UserEvent - The timer event that is to be signaled at the specified time
324 Type - The type of time that is specified in TriggerTime
325 TriggerTime - The number of 100ns units until the timer expires
329 EFI_SUCCESS - The event has been set to be signaled at the requested time
330 EFI_INVALID_PARAMETER - Event or Type is not valid
339 return EFI_INVALID_PARAMETER
;
342 if (Event
->Signature
!= EVENT_SIGNATURE
) {
343 return EFI_INVALID_PARAMETER
;
346 if (Type
< 0 || Type
> TimerRelative
|| !(Event
->Type
& EVT_TIMER
)) {
347 return EFI_INVALID_PARAMETER
;
350 CoreAcquireLock (&mEfiTimerLock
);
353 // If the timer is queued to the timer database, remove it
356 if (Event
->u
.Timer
.Link
.ForwardLink
!= NULL
) {
357 RemoveEntryList (&Event
->u
.Timer
.Link
);
358 Event
->u
.Timer
.Link
.ForwardLink
= NULL
;
361 Event
->u
.Timer
.TriggerTime
= 0;
362 Event
->u
.Timer
.Period
= 0;
364 if (Type
!= TimerCancel
) {
366 if (Type
== TimerPeriodic
) {
367 Event
->u
.Timer
.Period
= TriggerTime
;
370 Event
->u
.Timer
.TriggerTime
= CoreCurrentSystemTime () + TriggerTime
;
371 CoreInsertEventTimer (Event
);
373 if (TriggerTime
== 0) {
374 CoreSignalEvent (mEfiCheckTimerEvent
);
378 CoreReleaseLock (&mEfiTimerLock
);