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
23 Returns the current system time.
25 @return The current system time
30 CoreCurrentSystemTime (
35 Checks the sorted timer list against the current system time.
36 Signals any expired event timer.
38 @param CheckEvent Not used
39 @param Context Not used
51 Inserts the timer event.
53 @param Event Points to the internal structure of timer event
59 CoreInsertEventTimer (
67 static LIST_ENTRY mEfiTimerList
= INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList
);
68 static EFI_LOCK mEfiTimerLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL
- 1);
69 static EFI_EVENT mEfiCheckTimerEvent
;
71 static EFI_LOCK mEfiSystemTimeLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL
);
72 static UINT64 mEfiSystemTime
= 0;
80 Initializes timer support.
90 Status
= CoreCreateEvent (
97 ASSERT_EFI_ERROR (Status
);
102 Returns the current system time.
104 @return The current system time
109 CoreCurrentSystemTime (
115 CoreAcquireLock (&mEfiSystemTimeLock
);
116 SystemTime
= mEfiSystemTime
;
117 CoreReleaseLock (&mEfiSystemTimeLock
);
123 Called by the platform code to process a tick.
125 @param Duration The number of 100ns elasped since the last call
138 // Check runtiem flag in case there are ticks while exiting boot services
141 CoreAcquireLock (&mEfiSystemTimeLock
);
144 // Update the system time
147 mEfiSystemTime
+= Duration
;
150 // If the head of the list is expired, fire the timer event
154 if (!IsListEmpty (&mEfiTimerList
)) {
155 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
157 if (Event
->u
.Timer
.TriggerTime
<= mEfiSystemTime
) {
158 CoreSignalEvent (mEfiCheckTimerEvent
);
162 CoreReleaseLock (&mEfiSystemTimeLock
);
167 Checks the sorted timer list against the current system time.
168 Signals any expired event timer.
170 @param CheckEvent Not used
171 @param Context Not used
178 IN EFI_EVENT CheckEvent
,
186 // Check the timer database for expired timers
189 CoreAcquireLock (&mEfiTimerLock
);
190 SystemTime
= CoreCurrentSystemTime ();
192 while (!IsListEmpty (&mEfiTimerList
)) {
193 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
196 // If this timer is not expired, then we're done
199 if (Event
->u
.Timer
.TriggerTime
> SystemTime
) {
204 // Remove this timer from the timer queue
207 RemoveEntryList (&Event
->u
.Timer
.Link
);
208 Event
->u
.Timer
.Link
.ForwardLink
= NULL
;
213 CoreSignalEvent (Event
);
216 // If this is a periodic timer, set it
218 if (Event
->u
.Timer
.Period
) {
221 // Compute the timers new trigger time
224 Event
->u
.Timer
.TriggerTime
= Event
->u
.Timer
.TriggerTime
+ Event
->u
.Timer
.Period
;
227 // If that's before now, then reset the timer to start from now
229 if (Event
->u
.Timer
.TriggerTime
<= SystemTime
) {
230 Event
->u
.Timer
.TriggerTime
= SystemTime
;
231 CoreSignalEvent (mEfiCheckTimerEvent
);
238 CoreInsertEventTimer (Event
);
242 CoreReleaseLock (&mEfiTimerLock
);
247 Inserts the timer event.
249 @param Event Points to the internal structure of timer event
255 CoreInsertEventTimer (
263 ASSERT_LOCKED (&mEfiTimerLock
);
266 // Get the timer's trigger time
269 TriggerTime
= Event
->u
.Timer
.TriggerTime
;
272 // Insert the timer into the timer database in assending sorted order
275 for (Link
= mEfiTimerList
.ForwardLink
; Link
!= &mEfiTimerList
; Link
= Link
->ForwardLink
) {
276 Event2
= CR (Link
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
278 if (Event2
->u
.Timer
.TriggerTime
> TriggerTime
) {
283 InsertTailList (Link
, &Event
->u
.Timer
.Link
);
290 Sets the type of timer and the trigger time for a timer event.
292 @param UserEvent The timer event that is to be signaled at the
294 @param Type The type of time that is specified in
296 @param TriggerTime The number of 100ns units until the timer
299 @retval EFI_SUCCESS The event has been set to be signaled at the
301 @retval EFI_INVALID_PARAMETER Event or Type is not valid
307 IN EFI_EVENT UserEvent
,
308 IN EFI_TIMER_DELAY Type
,
309 IN UINT64 TriggerTime
317 return EFI_INVALID_PARAMETER
;
320 if (Event
->Signature
!= EVENT_SIGNATURE
) {
321 return EFI_INVALID_PARAMETER
;
324 if (Type
< 0 || Type
> TimerRelative
|| !(Event
->Type
& EVT_TIMER
)) {
325 return EFI_INVALID_PARAMETER
;
328 CoreAcquireLock (&mEfiTimerLock
);
331 // If the timer is queued to the timer database, remove it
334 if (Event
->u
.Timer
.Link
.ForwardLink
!= NULL
) {
335 RemoveEntryList (&Event
->u
.Timer
.Link
);
336 Event
->u
.Timer
.Link
.ForwardLink
= NULL
;
339 Event
->u
.Timer
.TriggerTime
= 0;
340 Event
->u
.Timer
.Period
= 0;
342 if (Type
!= TimerCancel
) {
344 if (Type
== TimerPeriodic
) {
345 Event
->u
.Timer
.Period
= TriggerTime
;
348 Event
->u
.Timer
.TriggerTime
= CoreCurrentSystemTime () + TriggerTime
;
349 CoreInsertEventTimer (Event
);
351 if (TriggerTime
== 0) {
352 CoreSignalEvent (mEfiCheckTimerEvent
);
356 CoreReleaseLock (&mEfiTimerLock
);