4 Copyright (c) 2006 - 2008, Intel Corporation. <BR>
5 All rights reserved. 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.
19 // Internal prototypes
22 Returns the current system time.
24 @return The current system time
28 CoreCurrentSystemTime (
33 Checks the sorted timer list against the current system time.
34 Signals any expired event timer.
36 @param CheckEvent Not used
37 @param Context Not used
43 IN EFI_EVENT CheckEvent
,
48 Inserts the timer event.
50 @param Event Points to the internal structure of timer event
55 CoreInsertEventTimer (
63 STATIC LIST_ENTRY mEfiTimerList
= INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList
);
64 STATIC EFI_LOCK mEfiTimerLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL
- 1);
65 STATIC EFI_EVENT mEfiCheckTimerEvent
;
67 STATIC EFI_LOCK mEfiSystemTimeLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL
);
68 STATIC UINT64 mEfiSystemTime
= 0;
76 Initializes timer support.
86 Status
= CoreCreateEvent (
93 ASSERT_EFI_ERROR (Status
);
98 Returns the current system time.
100 @return The current system time
104 CoreCurrentSystemTime (
110 CoreAcquireLock (&mEfiSystemTimeLock
);
111 SystemTime
= mEfiSystemTime
;
112 CoreReleaseLock (&mEfiSystemTimeLock
);
118 Called by the platform code to process a tick.
120 @param Duration The number of 100ns elasped since the last call
133 // Check runtiem flag in case there are ticks while exiting boot services
136 CoreAcquireLock (&mEfiSystemTimeLock
);
139 // Update the system time
142 mEfiSystemTime
+= Duration
;
145 // If the head of the list is expired, fire the timer event
149 if (!IsListEmpty (&mEfiTimerList
)) {
150 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
152 if (Event
->u
.Timer
.TriggerTime
<= mEfiSystemTime
) {
153 CoreSignalEvent (mEfiCheckTimerEvent
);
157 CoreReleaseLock (&mEfiSystemTimeLock
);
162 Checks the sorted timer list against the current system time.
163 Signals any expired event timer.
165 @param CheckEvent Not used
166 @param Context Not used
172 IN EFI_EVENT CheckEvent
,
180 // Check the timer database for expired timers
183 CoreAcquireLock (&mEfiTimerLock
);
184 SystemTime
= CoreCurrentSystemTime ();
186 while (!IsListEmpty (&mEfiTimerList
)) {
187 Event
= CR (mEfiTimerList
.ForwardLink
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
190 // If this timer is not expired, then we're done
193 if (Event
->u
.Timer
.TriggerTime
> SystemTime
) {
198 // Remove this timer from the timer queue
201 RemoveEntryList (&Event
->u
.Timer
.Link
);
202 Event
->u
.Timer
.Link
.ForwardLink
= NULL
;
207 CoreSignalEvent (Event
);
210 // If this is a periodic timer, set it
212 if (Event
->u
.Timer
.Period
) {
215 // Compute the timers new trigger time
218 Event
->u
.Timer
.TriggerTime
= Event
->u
.Timer
.TriggerTime
+ Event
->u
.Timer
.Period
;
221 // If that's before now, then reset the timer to start from now
223 if (Event
->u
.Timer
.TriggerTime
<= SystemTime
) {
224 Event
->u
.Timer
.TriggerTime
= SystemTime
;
225 CoreSignalEvent (mEfiCheckTimerEvent
);
232 CoreInsertEventTimer (Event
);
236 CoreReleaseLock (&mEfiTimerLock
);
241 Inserts the timer event.
243 @param Event Points to the internal structure of timer event
248 CoreInsertEventTimer (
256 ASSERT_LOCKED (&mEfiTimerLock
);
259 // Get the timer's trigger time
262 TriggerTime
= Event
->u
.Timer
.TriggerTime
;
265 // Insert the timer into the timer database in assending sorted order
268 for (Link
= mEfiTimerList
.ForwardLink
; Link
!= &mEfiTimerList
; Link
= Link
->ForwardLink
) {
269 Event2
= CR (Link
, IEVENT
, u
.Timer
.Link
, EVENT_SIGNATURE
);
271 if (Event2
->u
.Timer
.TriggerTime
> TriggerTime
) {
276 InsertTailList (Link
, &Event
->u
.Timer
.Link
);
283 Sets the type of timer and the trigger time for a timer event.
285 @param UserEvent The timer event that is to be signaled at the
287 @param Type The type of time that is specified in
289 @param TriggerTime The number of 100ns units until the timer
292 @retval EFI_SUCCESS The event has been set to be signaled at the
294 @retval EFI_INVALID_PARAMETER Event or Type is not valid
300 IN EFI_EVENT UserEvent
,
301 IN EFI_TIMER_DELAY Type
,
302 IN UINT64 TriggerTime
310 return EFI_INVALID_PARAMETER
;
313 if (Event
->Signature
!= EVENT_SIGNATURE
) {
314 return EFI_INVALID_PARAMETER
;
317 if (Type
< 0 || Type
> TimerRelative
|| !(Event
->Type
& EVT_TIMER
)) {
318 return EFI_INVALID_PARAMETER
;
321 CoreAcquireLock (&mEfiTimerLock
);
324 // If the timer is queued to the timer database, remove it
327 if (Event
->u
.Timer
.Link
.ForwardLink
!= NULL
) {
328 RemoveEntryList (&Event
->u
.Timer
.Link
);
329 Event
->u
.Timer
.Link
.ForwardLink
= NULL
;
332 Event
->u
.Timer
.TriggerTime
= 0;
333 Event
->u
.Timer
.Period
= 0;
335 if (Type
!= TimerCancel
) {
337 if (Type
== TimerPeriodic
) {
338 Event
->u
.Timer
.Period
= TriggerTime
;
341 Event
->u
.Timer
.TriggerTime
= CoreCurrentSystemTime () + TriggerTime
;
342 CoreInsertEventTimer (Event
);
344 if (TriggerTime
== 0) {
345 CoreSignalEvent (mEfiCheckTimerEvent
);
349 CoreReleaseLock (&mEfiTimerLock
);