diff options
Diffstat (limited to 'UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c')
-rw-r--r-- | UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c new file mode 100644 index 0000000000..5a632eaa24 --- /dev/null +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c @@ -0,0 +1,116 @@ +/** @file
+SMM Timer feature support
+
+Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PiSmmCpuDxeSmm.h"
+
+UINT64 mTimeoutTicker = 0;
+//
+// Number of counts in a roll-over cycle of the performance counter.
+//
+UINT64 mCycle = 0;
+//
+// Flag to indicate the performance counter is count-up or count-down.
+//
+BOOLEAN mCountDown;
+
+/**
+ Initialize Timer for SMM AP Sync.
+
+**/
+VOID
+InitializeSmmTimer (
+ VOID
+ )
+{
+ UINT64 TimerFrequency;
+ UINT64 Start;
+ UINT64 End;
+
+ TimerFrequency = GetPerformanceCounterProperties (&Start, &End);
+ mTimeoutTicker = DivU64x32 (
+ MultU64x64(TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)),
+ 1000 * 1000
+ );
+ if (End < Start) {
+ mCountDown = TRUE;
+ mCycle = Start - End;
+ } else {
+ mCountDown = FALSE;
+ mCycle = End - Start;
+ }
+}
+
+/**
+ Start Timer for SMM AP Sync.
+
+**/
+UINT64
+EFIAPI
+StartSyncTimer (
+ VOID
+ )
+{
+ return GetPerformanceCounter ();
+}
+
+
+/**
+ Check if the SMM AP Sync timer is timeout.
+
+ @param Timer The start timer from the begin.
+
+**/
+BOOLEAN
+EFIAPI
+IsSyncTimerTimeout (
+ IN UINT64 Timer
+ )
+{
+ UINT64 CurrentTimer;
+ UINT64 Delta;
+
+ CurrentTimer = GetPerformanceCounter ();
+ //
+ // We need to consider the case that CurrentTimer is equal to Timer
+ // when some timer runs too slow and CPU runs fast. We think roll over
+ // condition does not happen on this case.
+ //
+ if (mCountDown) {
+ //
+ // The performance counter counts down. Check for roll over condition.
+ //
+ if (CurrentTimer <= Timer) {
+ Delta = Timer - CurrentTimer;
+ } else {
+ //
+ // Handle one roll-over.
+ //
+ Delta = mCycle - (CurrentTimer - Timer) + 1;
+ }
+ } else {
+ //
+ // The performance counter counts up. Check for roll over condition.
+ //
+ if (CurrentTimer >= Timer) {
+ Delta = CurrentTimer - Timer;
+ } else {
+ //
+ // Handle one roll-over.
+ //
+ Delta = mCycle - (Timer - CurrentTimer) + 1;
+ }
+ }
+
+ return (BOOLEAN) (Delta >= mTimeoutTicker);
+}
|