]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c
UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmiCr3" with PatchInstructionX86()
[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 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
32 InitializeSmmTimer (
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
60 StartSyncTimer (
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
76 IsSyncTimerTimeout (
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 }