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