3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
28 // Internal prototypes
32 CoreCurrentSystemTime (
45 CoreInsertEventTimer (
53 static LIST_ENTRY mEfiTimerList
= INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList
);
54 static EFI_LOCK mEfiTimerLock
= EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL
- 1);
55 static EFI_EVENT mEfiCheckTimerEvent
;
57 static EFI_LOCK mEfiSystemTimeLock
= EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL
);
58 static UINT64 mEfiSystemTime
= 0;
72 Initializes timer support
86 Status
= CoreCreateEvent (
87 EFI_EVENT_NOTIFY_SIGNAL
,
88 EFI_TPL_HIGH_LEVEL
- 1,
93 ASSERT_EFI_ERROR (Status
);
98 CoreCurrentSystemTime (
105 Returns the current system time
113 Returns the current system time
119 CoreAcquireLock (&mEfiSystemTimeLock
);
120 SystemTime
= mEfiSystemTime
;
121 CoreReleaseLock (&mEfiSystemTimeLock
);
134 Called by the platform code to process a tick.
138 Duration - The number of 100ns elasped since the last call to TimerTick
149 // Check runtiem flag in case there are ticks while exiting boot services
152 CoreAcquireLock (&mEfiSystemTimeLock
);
155 // Update the system time
158 mEfiSystemTime
+= Duration
;
161 // If the head of the list is expired, fire the timer event
165 if (!IsListEmpty (&mEfiTimerList
)) {
166 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
168 if (Event
->u
.Timer
.TriggerTime
<= mEfiSystemTime
) {
169 CoreSignalEvent (mEfiCheckTimerEvent
);
173 CoreReleaseLock (&mEfiSystemTimeLock
);
179 IN EFI_EVENT CheckEvent
,
186 Checks the sorted timer list against the current system time.
187 Signals any expired event timer.
191 CheckEvent - Not used
205 // Check the timer database for expired timers
208 CoreAcquireLock (&mEfiTimerLock
);
209 SystemTime
= CoreCurrentSystemTime ();
211 while (!IsListEmpty (&mEfiTimerList
)) {
212 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
215 // If this timer is not expired, then we're done
218 if (Event
->u
.Timer
.TriggerTime
> SystemTime
) {
223 // Remove this timer from the timer queue
226 RemoveEntryList (&Event
->u
.Timer
.Link
);
227 Event
->u
.Timer
.Link
.ForwardLink
= NULL
;
232 CoreSignalEvent (Event
);
235 // If this is a periodic timer, set it
237 if (Event
->u
.Timer
.Period
) {
240 // Compute the timers new trigger time
243 Event
->u
.Timer
.TriggerTime
= Event
->u
.Timer
.TriggerTime
+ Event
->u
.Timer
.Period
;
246 // If that's before now, then reset the timer to start from now
248 if (Event
->u
.Timer
.TriggerTime
<= SystemTime
) {
249 Event
->u
.Timer
.TriggerTime
= SystemTime
;
250 CoreSignalEvent (mEfiCheckTimerEvent
);
257 CoreInsertEventTimer (Event
);
261 CoreReleaseLock (&mEfiTimerLock
);
266 CoreInsertEventTimer (
273 Inserts the timer event
277 Event - Points to the internal structure of timer event to be installed
289 ASSERT_LOCKED (&mEfiTimerLock
);
292 // Get the timer's trigger time
295 TriggerTime
= Event
->u
.Timer
.TriggerTime
;
298 // Insert the timer into the timer database in assending sorted order
301 for (Link
= mEfiTimerList
.ForwardLink
; Link
!= &mEfiTimerList
; Link
= Link
->ForwardLink
) {
302 Event2
= CR (Link
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
304 if (Event2
->u
.Timer
.TriggerTime
> TriggerTime
) {
309 InsertTailList (Link
, &Event
->u
.Timer
.Link
);
317 IN EFI_EVENT UserEvent
,
318 IN EFI_TIMER_DELAY Type
,
319 IN UINT64 TriggerTime
325 Sets the type of timer and the trigger time for a timer event.
329 UserEvent - The timer event that is to be signaled at the specified time
330 Type - The type of time that is specified in TriggerTime
331 TriggerTime - The number of 100ns units until the timer expires
335 EFI_SUCCESS - The event has been set to be signaled at the requested time
336 EFI_INVALID_PARAMETER - Event or Type is not valid
345 return EFI_INVALID_PARAMETER
;
348 if (Event
->Signature
!= EVENT_SIGNATURE
) {
349 return EFI_INVALID_PARAMETER
;
352 if (Type
< 0 || Type
> TimerRelative
|| !(Event
->Type
& EFI_EVENT_TIMER
)) {
353 return EFI_INVALID_PARAMETER
;
356 CoreAcquireLock (&mEfiTimerLock
);
359 // If the timer is queued to the timer database, remove it
362 if (Event
->u
.Timer
.Link
.ForwardLink
!= NULL
) {
363 RemoveEntryList (&Event
->u
.Timer
.Link
);
364 Event
->u
.Timer
.Link
.ForwardLink
= NULL
;
367 Event
->u
.Timer
.TriggerTime
= 0;
368 Event
->u
.Timer
.Period
= 0;
370 if (Type
!= TimerCancel
) {
372 if (Type
== TimerPeriodic
) {
373 Event
->u
.Timer
.Period
= TriggerTime
;
376 Event
->u
.Timer
.TriggerTime
= CoreCurrentSystemTime () + TriggerTime
;
377 CoreInsertEventTimer (Event
);
379 if (TriggerTime
== 0) {
380 CoreSignalEvent (mEfiCheckTimerEvent
);
384 CoreReleaseLock (&mEfiTimerLock
);