]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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 Check if the SMM AP Sync timer is timeout.
63
64 @param Timer The start timer from the begin.
65
66 **/
67 BOOLEAN
68 EFIAPI
69 IsSyncTimerTimeout (
70 IN UINT64 Timer
71 )
72 {
73 UINT64 CurrentTimer;
74 UINT64 Delta;
75
76 CurrentTimer = GetPerformanceCounter ();
77 //
78 // We need to consider the case that CurrentTimer is equal to Timer
79 // when some timer runs too slow and CPU runs fast. We think roll over
80 // condition does not happen on this case.
81 //
82 if (mCountDown) {
83 //
84 // The performance counter counts down. Check for roll over condition.
85 //
86 if (CurrentTimer <= Timer) {
87 Delta = Timer - CurrentTimer;
88 } else {
89 //
90 // Handle one roll-over.
91 //
92 Delta = mCycle - (CurrentTimer - Timer) + 1;
93 }
94 } else {
95 //
96 // The performance counter counts up. Check for roll over condition.
97 //
98 if (CurrentTimer >= Timer) {
99 Delta = CurrentTimer - Timer;
100 } else {
101 //
102 // Handle one roll-over.
103 //
104 Delta = mCycle - (Timer - CurrentTimer) + 1;
105 }
106 }
107
108 return (BOOLEAN)(Delta >= mTimeoutTicker);
109 }