/** @file SMM Timer feature support Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #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); }