4 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 LIST_ENTRY mEfiTimerList
= INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList
);
24 EFI_LOCK mEfiTimerLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL
- 1);
25 EFI_EVENT mEfiCheckTimerEvent
= NULL
;
27 EFI_LOCK mEfiSystemTimeLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL
);
28 UINT64 mEfiSystemTime
= 0;
34 Inserts the timer event.
36 @param Event Points to the internal structure of timer event
41 CoreInsertEventTimer (
49 ASSERT_LOCKED (&mEfiTimerLock
);
52 // Get the timer's trigger time
54 TriggerTime
= Event
->Timer
.TriggerTime
;
57 // Insert the timer into the timer database in assending sorted order
59 for (Link
= mEfiTimerList
.ForwardLink
; Link
!= &mEfiTimerList
; Link
= Link
->ForwardLink
) {
60 Event2
= CR (Link
, IEVENT
, Timer
.Link
, EVENT_SIGNATURE
);
62 if (Event2
->Timer
.TriggerTime
> TriggerTime
) {
67 InsertTailList (Link
, &Event
->Timer
.Link
);
71 Returns the current system time.
73 @return The current system time
77 CoreCurrentSystemTime (
83 CoreAcquireLock (&mEfiSystemTimeLock
);
84 SystemTime
= mEfiSystemTime
;
85 CoreReleaseLock (&mEfiSystemTimeLock
);
91 Checks the sorted timer list against the current system time.
92 Signals any expired event timer.
94 @param CheckEvent Not used
95 @param Context Not used
101 IN EFI_EVENT CheckEvent
,
109 // Check the timer database for expired timers
111 CoreAcquireLock (&mEfiTimerLock
);
112 SystemTime
= CoreCurrentSystemTime ();
114 while (!IsListEmpty (&mEfiTimerList
)) {
115 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, Timer
.Link
, EVENT_SIGNATURE
);
118 // If this timer is not expired, then we're done
120 if (Event
->Timer
.TriggerTime
> SystemTime
) {
125 // Remove this timer from the timer queue
128 RemoveEntryList (&Event
->Timer
.Link
);
129 Event
->Timer
.Link
.ForwardLink
= NULL
;
134 CoreSignalEvent (Event
);
137 // If this is a periodic timer, set it
139 if (Event
->Timer
.Period
!= 0) {
141 // Compute the timers new trigger time
143 Event
->Timer
.TriggerTime
= Event
->Timer
.TriggerTime
+ Event
->Timer
.Period
;
146 // If that's before now, then reset the timer to start from now
148 if (Event
->Timer
.TriggerTime
<= SystemTime
) {
149 Event
->Timer
.TriggerTime
= SystemTime
;
150 CoreSignalEvent (mEfiCheckTimerEvent
);
156 CoreInsertEventTimer (Event
);
160 CoreReleaseLock (&mEfiTimerLock
);
165 Initializes timer support.
169 CoreInitializeTimer (
175 Status
= CoreCreateEventInternal (
183 ASSERT_EFI_ERROR (Status
);
188 Called by the platform code to process a tick.
190 @param Duration The number of 100ns elasped since the last call
203 // Check runtiem flag in case there are ticks while exiting boot services
205 CoreAcquireLock (&mEfiSystemTimeLock
);
208 // Update the system time
210 mEfiSystemTime
+= Duration
;
213 // If the head of the list is expired, fire the timer event
216 if (!IsListEmpty (&mEfiTimerList
)) {
217 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, Timer
.Link
, EVENT_SIGNATURE
);
219 if (Event
->Timer
.TriggerTime
<= mEfiSystemTime
) {
220 CoreSignalEvent (mEfiCheckTimerEvent
);
224 CoreReleaseLock (&mEfiSystemTimeLock
);
230 Sets the type of timer and the trigger time for a timer event.
232 @param UserEvent The timer event that is to be signaled at the
234 @param Type The type of time that is specified in
236 @param TriggerTime The number of 100ns units until the timer
239 @retval EFI_SUCCESS The event has been set to be signaled at the
241 @retval EFI_INVALID_PARAMETER Event or Type is not valid
247 IN EFI_EVENT UserEvent
,
248 IN EFI_TIMER_DELAY Type
,
249 IN UINT64 TriggerTime
257 return EFI_INVALID_PARAMETER
;
260 if (Event
->Signature
!= EVENT_SIGNATURE
) {
261 return EFI_INVALID_PARAMETER
;
264 if ((UINT32
)Type
> TimerRelative
|| (Event
->Type
& EVT_TIMER
) == 0) {
265 return EFI_INVALID_PARAMETER
;
268 CoreAcquireLock (&mEfiTimerLock
);
271 // If the timer is queued to the timer database, remove it
273 if (Event
->Timer
.Link
.ForwardLink
!= NULL
) {
274 RemoveEntryList (&Event
->Timer
.Link
);
275 Event
->Timer
.Link
.ForwardLink
= NULL
;
278 Event
->Timer
.TriggerTime
= 0;
279 Event
->Timer
.Period
= 0;
281 if (Type
!= TimerCancel
) {
283 if (Type
== TimerPeriodic
) {
284 if (TriggerTime
== 0) {
285 gTimer
->GetTimerPeriod (gTimer
, &TriggerTime
);
287 Event
->Timer
.Period
= TriggerTime
;
290 Event
->Timer
.TriggerTime
= CoreCurrentSystemTime () + TriggerTime
;
291 CoreInsertEventTimer (Event
);
293 if (TriggerTime
== 0) {
294 CoreSignalEvent (mEfiCheckTimerEvent
);
298 CoreReleaseLock (&mEfiTimerLock
);