1 /** @file 2 SMM Timer feature support 3 4 Copyright (c) 2009 - 2015, 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 9 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. 12 13 **/ 14 15 #include "PiSmmCpuDxeSmm.h" 16 17 UINT64 mTimeoutTicker = 0; 18 // 19 // Number of counts in a roll-over cycle of the performance counter. 20 // 21 UINT64 mCycle = 0; 22 // 23 // Flag to indicate the performance counter is count-up or count-down. 24 // 25 BOOLEAN mCountDown; 26 27 /** 28 Initialize Timer for SMM AP Sync. 29 30 **/ 31 VOID InitializeSmmTimer(VOID)32InitializeSmmTimer ( 33 VOID 34 ) 35 { 36 UINT64 TimerFrequency; 37 UINT64 Start; 38 UINT64 End; 39 40 TimerFrequency = GetPerformanceCounterProperties (&Start, &End); 41 mTimeoutTicker = DivU64x32 ( 42 MultU64x64(TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)), 43 1000 * 1000 44 ); 45 if (End < Start) { 46 mCountDown = TRUE; 47 mCycle = Start - End; 48 } else { 49 mCountDown = FALSE; 50 mCycle = End - Start; 51 } 52 } 53 54 /** 55 Start Timer for SMM AP Sync. 56 57 **/ 58 UINT64 59 EFIAPI StartSyncTimer(VOID)60StartSyncTimer ( 61 VOID 62 ) 63 { 64 return GetPerformanceCounter (); 65 } 66 67 68 /** 69 Check if the SMM AP Sync timer is timeout. 70 71 @param Timer The start timer from the begin. 72 73 **/ 74 BOOLEAN 75 EFIAPI IsSyncTimerTimeout(IN UINT64 Timer)76IsSyncTimerTimeout ( 77 IN UINT64 Timer 78 ) 79 { 80 UINT64 CurrentTimer; 81 UINT64 Delta; 82 83 CurrentTimer = GetPerformanceCounter (); 84 // 85 // We need to consider the case that CurrentTimer is equal to Timer 86 // when some timer runs too slow and CPU runs fast. We think roll over 87 // condition does not happen on this case. 88 // 89 if (mCountDown) { 90 // 91 // The performance counter counts down. Check for roll over condition. 92 // 93 if (CurrentTimer <= Timer) { 94 Delta = Timer - CurrentTimer; 95 } else { 96 // 97 // Handle one roll-over. 98 // 99 Delta = mCycle - (CurrentTimer - Timer) + 1; 100 } 101 } else { 102 // 103 // The performance counter counts up. Check for roll over condition. 104 // 105 if (CurrentTimer >= Timer) { 106 Delta = CurrentTimer - Timer; 107 } else { 108 // 109 // Handle one roll-over. 110 // 111 Delta = mCycle - (Timer - CurrentTimer) + 1; 112 } 113 } 114 115 return (BOOLEAN) (Delta >= mTimeoutTicker); 116 } 117